I: pbuilder: network access will be disabled during build I: Current time: Thu Feb 12 23:15:16 +14 2026 I: pbuilder-time-stamp: 1770887716 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/unstable-reproducible-base.tgz] I: copying local configuration W: --override-config is not set; not updating apt.conf Read the manpage for details. I: mounting /proc filesystem I: mounting /sys filesystem I: creating /{dev,run}/shm I: mounting /dev/pts filesystem I: redirecting /dev/ptmx to /dev/pts/ptmx I: policy-rc.d already exists I: Copying source file I: copying [python-pook_2.1.3-1.dsc] I: copying [./python-pook_2.1.3.orig.tar.gz] I: copying [./python-pook_2.1.3-1.debian.tar.xz] I: Extracting source dpkg-source: warning: cannot verify inline signature for ./python-pook_2.1.3-1.dsc: unsupported subcommand dpkg-source: info: extracting python-pook in python-pook-2.1.3 dpkg-source: info: unpacking python-pook_2.1.3.orig.tar.gz dpkg-source: info: unpacking python-pook_2.1.3-1.debian.tar.xz dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: applying 010_remove-privacy-breach-images.patch dpkg-source: info: applying 020_fix-sufix_versions.patch I: Not using root during the build. I: Installing the build-deps I: user script /srv/workspace/pbuilder/263293/tmp/hooks/D01_modify_environment starting debug: Running on ionos15-amd64. I: Changing host+domainname to test build reproducibility I: Adding a custom variable just for the fun of it... I: Changing /bin/sh to bash '/bin/sh' -> '/bin/bash' lrwxrwxrwx 1 root root 9 Feb 12 09:15 /bin/sh -> /bin/bash I: Setting pbuilder2's login shell to /bin/bash I: Setting pbuilder2's GECOS to second user,second room,second work-phone,second home-phone,second other I: user script /srv/workspace/pbuilder/263293/tmp/hooks/D01_modify_environment finished I: user script /srv/workspace/pbuilder/263293/tmp/hooks/D02_print_environment starting I: set BASH=/bin/sh BASHOPTS=checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=([0]="12" [1]="0") BASH_LOADABLES_PATH=/usr/local/lib/bash:/usr/lib/bash:/opt/local/lib/bash:/usr/pkg/lib/bash:/opt/pkg/lib/bash:. BASH_SOURCE=([0]="/tmp/hooks/D02_print_environment" [1]="/tmp/hooks/D02_print_environment") BASH_VERSINFO=([0]="5" [1]="2" [2]="37" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") BASH_VERSION='5.2.37(1)-release' BUILDDIR=/build/reproducible-path BUILDUSERGECOS='second user,second room,second work-phone,second home-phone,second other' BUILDUSERNAME=pbuilder2 BUILD_ARCH=amd64 DEBIAN_FRONTEND=noninteractive DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=42 ' DIRSTACK=() DISTRIBUTION=unstable EUID=0 FUNCNAME=([0]="Echo" [1]="main") GROUPS=() HOME=/root HOSTNAME=i-capture-the-hostname HOSTTYPE=x86_64 HOST_ARCH=amd64 IFS=' ' INVOCATION_ID=7db2582abf2347f58342886315df2944 LANG=C LANGUAGE=et_EE:et LC_ALL=C MACHTYPE=x86_64-pc-linux-gnu MAIL=/var/mail/root OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path PBCURRENTCOMMANDLINEOPERATION=build PBUILDER_OPERATION=build PBUILDER_PKGDATADIR=/usr/share/pbuilder PBUILDER_PKGLIBDIR=/usr/lib/pbuilder PBUILDER_SYSCONFDIR=/etc PIPESTATUS=([0]="0") POSIXLY_CORRECT=y PPID=263293 PS4='+ ' PWD=/ SHELL=/bin/bash SHELLOPTS=braceexpand:errexit:hashall:interactive-comments:posix SHLVL=3 SUDO_COMMAND='/usr/bin/timeout -k 24.1h 24h /usr/bin/ionice -c 3 /usr/bin/nice -n 11 /usr/bin/unshare --uts -- /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/r-b-build.qeXNtoIo/pbuilderrc_KQDx --distribution unstable --hookdir /etc/pbuilder/rebuild-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/unstable-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.qeXNtoIo/b2 --logfile b2/build.log python-pook_2.1.3-1.dsc' SUDO_GID=111 SUDO_UID=106 SUDO_USER=jenkins TERM=unknown TZ=/usr/share/zoneinfo/Etc/GMT-14 UID=0 USER=root _='I: set' http_proxy=http://213.165.73.152:3128 I: uname -a Linux i-capture-the-hostname 6.11.10+bpo-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.11.10-1~bpo12+1 (2024-12-19) x86_64 GNU/Linux I: ls -l /bin lrwxrwxrwx 1 root root 7 Nov 22 2024 /bin -> usr/bin I: user script /srv/workspace/pbuilder/263293/tmp/hooks/D02_print_environment finished -> Attempting to satisfy build-dependencies -> Creating pbuilder-satisfydepends-dummy package Package: pbuilder-satisfydepends-dummy Version: 0.invalid.0 Architecture: amd64 Maintainer: Debian Pbuilder Team Description: Dummy package to satisfy dependencies with aptitude - created by pbuilder This package was created automatically by pbuilder to satisfy the build-dependencies of the package being currently built. Depends: debhelper-compat (= 13), dh-sequence-python3, pybuild-plugin-pyproject, python3-all, python3-setuptools, python3-hatchling, python3-httpx, python3-furl, python3-xmltodict, python3-jsonschema, python3-pytest, python3-urllib3, python3-requests, python3-aiohttp, python3-pytest-cov, python3-pytest-httpbin, python3-sphinx, python3-sphinx-rtd-theme dpkg-deb: building package 'pbuilder-satisfydepends-dummy' in '/tmp/satisfydepends-aptitude/pbuilder-satisfydepends-dummy.deb'. Selecting previously unselected package pbuilder-satisfydepends-dummy. (Reading database ... 19848 files and directories currently installed.) Preparing to unpack .../pbuilder-satisfydepends-dummy.deb ... Unpacking pbuilder-satisfydepends-dummy (0.invalid.0) ... dpkg: pbuilder-satisfydepends-dummy: dependency problems, but configuring anyway as you requested: pbuilder-satisfydepends-dummy depends on debhelper-compat (= 13); however: Package debhelper-compat is not installed. pbuilder-satisfydepends-dummy depends on dh-sequence-python3; however: Package dh-sequence-python3 is not installed. pbuilder-satisfydepends-dummy depends on pybuild-plugin-pyproject; however: Package pybuild-plugin-pyproject is not installed. pbuilder-satisfydepends-dummy depends on python3-all; however: Package python3-all is not installed. pbuilder-satisfydepends-dummy depends on python3-setuptools; however: Package python3-setuptools is not installed. pbuilder-satisfydepends-dummy depends on python3-hatchling; however: Package python3-hatchling is not installed. pbuilder-satisfydepends-dummy depends on python3-httpx; however: Package python3-httpx is not installed. pbuilder-satisfydepends-dummy depends on python3-furl; however: Package python3-furl is not installed. pbuilder-satisfydepends-dummy depends on python3-xmltodict; however: Package python3-xmltodict is not installed. pbuilder-satisfydepends-dummy depends on python3-jsonschema; however: Package python3-jsonschema is not installed. pbuilder-satisfydepends-dummy depends on python3-pytest; however: Package python3-pytest is not installed. pbuilder-satisfydepends-dummy depends on python3-urllib3; however: Package python3-urllib3 is not installed. pbuilder-satisfydepends-dummy depends on python3-requests; however: Package python3-requests is not installed. pbuilder-satisfydepends-dummy depends on python3-aiohttp; however: Package python3-aiohttp is not installed. pbuilder-satisfydepends-dummy depends on python3-pytest-cov; however: Package python3-pytest-cov is not installed. pbuilder-satisfydepends-dummy depends on python3-pytest-httpbin; however: Package python3-pytest-httpbin is not installed. pbuilder-satisfydepends-dummy depends on python3-sphinx; however: Package python3-sphinx is not installed. pbuilder-satisfydepends-dummy depends on python3-sphinx-rtd-theme; however: Package python3-sphinx-rtd-theme is not installed. Setting up pbuilder-satisfydepends-dummy (0.invalid.0) ... Reading package lists... Building dependency tree... Reading state information... Initializing package states... Writing extended state information... Building tag database... pbuilder-satisfydepends-dummy is already installed at the requested version (0.invalid.0) pbuilder-satisfydepends-dummy is already installed at the requested version (0.invalid.0) The following NEW packages will be installed: autoconf{a} automake{a} autopoint{a} autotools-dev{a} bsdextrautils{a} ca-certificates{a} debhelper{a} dh-autoreconf{a} dh-python{a} dh-strip-nondeterminism{a} docutils-common{a} dwz{a} file{a} fonts-font-awesome{a} fonts-lato{a} gettext{a} gettext-base{a} groff-base{a} intltool-debian{a} libarchive-zip-perl{a} libbrotli1{a} libcom-err2{a} libdebhelper-perl{a} libelf1t64{a} libexpat1{a} libffi8{a} libfile-stripnondeterminism-perl{a} libgssapi-krb5-2{a} libicu72{a} libjs-jquery{a} libjs-jquery-hotkeys{a} libjs-jquery-isonscreen{a} libjs-jquery-metadata{a} libjs-jquery-tablesorter{a} libjs-jquery-throttle-debounce{a} libjs-sphinxdoc{a} libjs-underscore{a} libjson-perl{a} libk5crypto3{a} libkeyutils1{a} libkrb5-3{a} libkrb5support0{a} libmagic-mgc{a} libmagic1t64{a} libnsl2{a} libpipeline1{a} libpython3-stdlib{a} libpython3.12-minimal{a} libpython3.12-stdlib{a} libpython3.13-minimal{a} libpython3.13-stdlib{a} libreadline8t64{a} libtirpc-common{a} libtirpc3t64{a} libtool{a} libuchardet0{a} libunistring5{a} libxml2{a} libyaml-0-2{a} m4{a} man-db{a} media-types{a} netbase{a} openssl{a} po-debconf{a} pybuild-plugin-pyproject{a} python-babel-localedata{a} python3{a} python3-aiohappyeyeballs{a} python3-aiohttp{a} python3-aiosignal{a} python3-alabaster{a} python3-all{a} python3-anyio{a} python3-async-timeout{a} python3-attr{a} python3-autocommand{a} python3-babel{a} python3-blinker{a} python3-brotli{a} python3-brotlicffi{a} python3-build{a} python3-certifi{a} python3-cffi-backend{a} python3-chardet{a} python3-charset-normalizer{a} python3-click{a} python3-coverage{a} python3-decorator{a} python3-defusedxml{a} python3-docutils{a} python3-flasgger{a} python3-flask{a} python3-frozenlist{a} python3-furl{a} python3-greenlet{a} python3-h11{a} python3-hatchling{a} python3-httpbin{a} python3-httpcore{a} python3-httpx{a} python3-idna{a} python3-imagesize{a} python3-inflect{a} python3-iniconfig{a} python3-installer{a} python3-itsdangerous{a} python3-jaraco.context{a} python3-jaraco.functools{a} python3-jaraco.text{a} python3-jinja2{a} python3-jsonschema{a} python3-jsonschema-specifications{a} python3-markdown-it{a} python3-markupsafe{a} python3-mdurl{a} python3-minimal{a} python3-mistune{a} python3-more-itertools{a} python3-multidict{a} python3-orderedmultidict{a} python3-packaging{a} python3-pathspec{a} python3-pkg-resources{a} python3-pluggy{a} python3-pygments{a} python3-pyproject-hooks{a} python3-pytest{a} python3-pytest-cov{a} python3-pytest-httpbin{a} python3-referencing{a} python3-requests{a} python3-rich{a} python3-roman{a} python3-rpds-py{a} python3-setuptools{a} python3-six{a} python3-sniffio{a} python3-snowballstemmer{a} python3-sphinx{a} python3-sphinx-rtd-theme{a} python3-sphinxcontrib.jquery{a} python3-toml{a} python3-trove-classifiers{a} python3-typeguard{a} python3-typing-extensions{a} python3-urllib3{a} python3-werkzeug{a} python3-wheel{a} python3-xmltodict{a} python3-yaml{a} python3-yarl{a} python3-zipp{a} python3.12{a} python3.12-minimal{a} python3.13{a} python3.13-minimal{a} readline-common{a} sensible-utils{a} sgml-base{a} sphinx-common{a} sphinx-rtd-theme-common{a} tzdata{a} xml-core{a} The following packages are RECOMMENDED but will NOT be installed: curl gunicorn javascript-common krb5-locales libarchive-cpio-perl libjson-xs-perl libltdl-dev libmail-sendmail-perl libpaper-utils lynx python3-aiodns python3-asgiref python3-dotenv python3-fqdn python3-isoduration python3-json-pointer python3-openssl python3-pil python3-pyinotify python3-rfc3339-validator python3-rfc3986-validator python3-rfc3987 python3-simplejson python3-uritemplate python3-webcolors wget 0 packages upgraded, 164 newly installed, 0 to remove and 0 not upgraded. Need to get 56.1 MB of archives. After unpacking 235 MB will be used. Writing extended state information... Get: 1 http://deb.debian.org/debian unstable/main amd64 fonts-lato all 2.015-1 [2780 kB] Get: 2 http://deb.debian.org/debian unstable/main amd64 libpython3.13-minimal amd64 3.13.1-3 [858 kB] Get: 3 http://deb.debian.org/debian unstable/main amd64 libexpat1 amd64 2.6.4-1 [106 kB] Get: 4 http://deb.debian.org/debian unstable/main amd64 python3.13-minimal amd64 3.13.1-3 [2202 kB] Get: 5 http://deb.debian.org/debian unstable/main amd64 python3-minimal amd64 3.13.1-2 [27.0 kB] Get: 6 http://deb.debian.org/debian unstable/main amd64 media-types all 10.1.0 [26.9 kB] Get: 7 http://deb.debian.org/debian unstable/main amd64 netbase all 6.4 [12.8 kB] Get: 8 http://deb.debian.org/debian unstable/main amd64 tzdata all 2024b-5 [256 kB] Get: 9 http://deb.debian.org/debian unstable/main amd64 libffi8 amd64 3.4.6-1 [23.6 kB] Get: 10 http://deb.debian.org/debian unstable/main amd64 readline-common all 8.2-6 [69.4 kB] Get: 11 http://deb.debian.org/debian unstable/main amd64 libreadline8t64 amd64 8.2-6 [169 kB] Get: 12 http://deb.debian.org/debian unstable/main amd64 libpython3.13-stdlib amd64 3.13.1-3 [1973 kB] Get: 13 http://deb.debian.org/debian unstable/main amd64 python3.13 amd64 3.13.1-3 [740 kB] Get: 14 http://deb.debian.org/debian unstable/main amd64 libpython3-stdlib amd64 3.13.1-2 [9952 B] Get: 15 http://deb.debian.org/debian unstable/main amd64 python3 amd64 3.13.1-2 [28.0 kB] Get: 16 http://deb.debian.org/debian unstable/main amd64 libpython3.12-minimal amd64 3.12.8-4 [816 kB] Get: 17 http://deb.debian.org/debian unstable/main amd64 python3.12-minimal amd64 3.12.8-4 [2162 kB] Get: 18 http://deb.debian.org/debian unstable/main amd64 sgml-base all 1.31 [15.4 kB] Get: 19 http://deb.debian.org/debian unstable/main amd64 sensible-utils all 0.0.24 [24.8 kB] Get: 20 http://deb.debian.org/debian unstable/main amd64 openssl amd64 3.4.0-2 [1422 kB] Get: 21 http://deb.debian.org/debian unstable/main amd64 ca-certificates all 20241223 [164 kB] Get: 22 http://deb.debian.org/debian unstable/main amd64 libmagic-mgc amd64 1:5.45-3+b1 [314 kB] Get: 23 http://deb.debian.org/debian unstable/main amd64 libmagic1t64 amd64 1:5.45-3+b1 [108 kB] Get: 24 http://deb.debian.org/debian unstable/main amd64 file amd64 1:5.45-3+b1 [43.3 kB] Get: 25 http://deb.debian.org/debian unstable/main amd64 gettext-base amd64 0.22.5-4 [200 kB] Get: 26 http://deb.debian.org/debian unstable/main amd64 libuchardet0 amd64 0.0.8-1+b2 [68.9 kB] Get: 27 http://deb.debian.org/debian unstable/main amd64 groff-base amd64 1.23.0-7 [1185 kB] Get: 28 http://deb.debian.org/debian unstable/main amd64 bsdextrautils amd64 2.40.2-14 [92.1 kB] Get: 29 http://deb.debian.org/debian unstable/main amd64 libpipeline1 amd64 1.5.8-1 [42.0 kB] Get: 30 http://deb.debian.org/debian unstable/main amd64 man-db amd64 2.13.0-1 [1420 kB] Get: 31 http://deb.debian.org/debian unstable/main amd64 m4 amd64 1.4.19-5 [294 kB] Get: 32 http://deb.debian.org/debian unstable/main amd64 autoconf all 2.72-3 [493 kB] Get: 33 http://deb.debian.org/debian unstable/main amd64 autotools-dev all 20220109.1 [51.6 kB] Get: 34 http://deb.debian.org/debian unstable/main amd64 automake all 1:1.16.5-1.3 [823 kB] Get: 35 http://deb.debian.org/debian unstable/main amd64 autopoint all 0.22.5-4 [723 kB] Get: 36 http://deb.debian.org/debian unstable/main amd64 libdebhelper-perl all 13.23 [90.6 kB] Get: 37 http://deb.debian.org/debian unstable/main amd64 libtool all 2.5.4-2 [539 kB] Get: 38 http://deb.debian.org/debian unstable/main amd64 dh-autoreconf all 20 [17.1 kB] Get: 39 http://deb.debian.org/debian unstable/main amd64 libarchive-zip-perl all 1.68-1 [104 kB] Get: 40 http://deb.debian.org/debian unstable/main amd64 libfile-stripnondeterminism-perl all 1.14.0-1 [19.5 kB] Get: 41 http://deb.debian.org/debian unstable/main amd64 dh-strip-nondeterminism all 1.14.0-1 [8448 B] Get: 42 http://deb.debian.org/debian unstable/main amd64 libelf1t64 amd64 0.192-4 [189 kB] Get: 43 http://deb.debian.org/debian unstable/main amd64 dwz amd64 0.15-1+b1 [110 kB] Get: 44 http://deb.debian.org/debian unstable/main amd64 libunistring5 amd64 1.3-1 [476 kB] Get: 45 http://deb.debian.org/debian unstable/main amd64 libicu72 amd64 72.1-6 [9421 kB] Get: 46 http://deb.debian.org/debian unstable/main amd64 libxml2 amd64 2.12.7+dfsg+really2.9.14-0.2+b1 [699 kB] Get: 47 http://deb.debian.org/debian unstable/main amd64 gettext amd64 0.22.5-4 [1600 kB] Get: 48 http://deb.debian.org/debian unstable/main amd64 intltool-debian all 0.35.0+20060710.6 [22.9 kB] Get: 49 http://deb.debian.org/debian unstable/main amd64 po-debconf all 1.0.21+nmu1 [248 kB] Get: 50 http://deb.debian.org/debian unstable/main amd64 debhelper all 13.23 [919 kB] Get: 51 http://deb.debian.org/debian unstable/main amd64 python3-autocommand all 2.2.2-3 [13.6 kB] Get: 52 http://deb.debian.org/debian unstable/main amd64 python3-more-itertools all 10.5.0-1 [63.8 kB] Get: 53 http://deb.debian.org/debian unstable/main amd64 python3-typing-extensions all 4.12.2-2 [73.0 kB] Get: 54 http://deb.debian.org/debian unstable/main amd64 python3-typeguard all 4.4.1-1 [37.0 kB] Get: 55 http://deb.debian.org/debian unstable/main amd64 python3-inflect all 7.3.1-2 [32.4 kB] Get: 56 http://deb.debian.org/debian unstable/main amd64 python3-jaraco.context all 6.0.0-1 [7984 B] Get: 57 http://deb.debian.org/debian unstable/main amd64 python3-jaraco.functools all 4.1.0-1 [12.0 kB] Get: 58 http://deb.debian.org/debian unstable/main amd64 python3-pkg-resources all 75.6.0-1 [222 kB] Get: 59 http://deb.debian.org/debian unstable/main amd64 python3-jaraco.text all 4.0.0-1 [11.4 kB] Get: 60 http://deb.debian.org/debian unstable/main amd64 python3-zipp all 3.21.0-1 [10.6 kB] Get: 61 http://deb.debian.org/debian unstable/main amd64 python3-setuptools all 75.6.0-1 [720 kB] Get: 62 http://deb.debian.org/debian unstable/main amd64 dh-python all 6.20250108 [113 kB] Get: 63 http://deb.debian.org/debian unstable/main amd64 xml-core all 0.19 [20.1 kB] Get: 64 http://deb.debian.org/debian unstable/main amd64 docutils-common all 0.21.2+dfsg-2 [128 kB] Get: 65 http://deb.debian.org/debian unstable/main amd64 fonts-font-awesome all 5.0.10+really4.7.0~dfsg-4.1 [517 kB] Get: 66 http://deb.debian.org/debian unstable/main amd64 libbrotli1 amd64 1.1.0-2+b6 [302 kB] Get: 67 http://deb.debian.org/debian unstable/main amd64 libcom-err2 amd64 1.47.2-1 [24.0 kB] Get: 68 http://deb.debian.org/debian unstable/main amd64 libkrb5support0 amd64 1.21.3-3 [32.5 kB] Get: 69 http://deb.debian.org/debian unstable/main amd64 libk5crypto3 amd64 1.21.3-3 [79.9 kB] Get: 70 http://deb.debian.org/debian unstable/main amd64 libkeyutils1 amd64 1.6.3-4 [9092 B] Get: 71 http://deb.debian.org/debian unstable/main amd64 libkrb5-3 amd64 1.21.3-3 [324 kB] Get: 72 http://deb.debian.org/debian unstable/main amd64 libgssapi-krb5-2 amd64 1.21.3-3 [136 kB] Get: 73 http://deb.debian.org/debian unstable/main amd64 libjs-jquery all 3.6.1+dfsg+~3.5.14-1 [326 kB] Get: 74 http://deb.debian.org/debian unstable/main amd64 libjs-jquery-hotkeys all 0.2.0-1 [12.6 kB] Get: 75 http://deb.debian.org/debian unstable/main amd64 libjs-jquery-isonscreen all 1.2.0-1.1 [3196 B] Get: 76 http://deb.debian.org/debian unstable/main amd64 libjs-jquery-metadata all 12-4 [6532 B] Get: 77 http://deb.debian.org/debian unstable/main amd64 libjs-jquery-tablesorter all 1:2.31.3+dfsg1-4 [184 kB] Get: 78 http://deb.debian.org/debian unstable/main amd64 libjs-jquery-throttle-debounce all 1.1+dfsg.1-2 [12.2 kB] Get: 79 http://deb.debian.org/debian unstable/main amd64 libjs-underscore all 1.13.4~dfsg+~1.11.4-3 [116 kB] Get: 80 http://deb.debian.org/debian unstable/main amd64 libjs-sphinxdoc all 8.1.3-4 [30.4 kB] Get: 81 http://deb.debian.org/debian unstable/main amd64 libjson-perl all 4.10000-1 [87.5 kB] Get: 82 http://deb.debian.org/debian unstable/main amd64 libtirpc-common all 1.3.4+ds-1.3 [10.9 kB] Get: 83 http://deb.debian.org/debian unstable/main amd64 libtirpc3t64 amd64 1.3.4+ds-1.3+b1 [83.1 kB] Get: 84 http://deb.debian.org/debian unstable/main amd64 libnsl2 amd64 1.3.0-3+b3 [40.6 kB] Get: 85 http://deb.debian.org/debian unstable/main amd64 libpython3.12-stdlib amd64 3.12.8-4 [1973 kB] Get: 86 http://deb.debian.org/debian unstable/main amd64 libyaml-0-2 amd64 0.2.5-2 [52.5 kB] Get: 87 http://deb.debian.org/debian unstable/main amd64 python3-packaging all 24.2-1 [55.3 kB] Get: 88 http://deb.debian.org/debian unstable/main amd64 python3-pyproject-hooks all 1.2.0-1 [11.7 kB] Get: 89 http://deb.debian.org/debian unstable/main amd64 python3-toml all 0.10.2-1 [16.2 kB] Get: 90 http://deb.debian.org/debian unstable/main amd64 python3-wheel all 0.45.1-1 [56.7 kB] Get: 91 http://deb.debian.org/debian unstable/main amd64 python3-build all 1.2.2-1 [36.0 kB] Get: 92 http://deb.debian.org/debian unstable/main amd64 python3-installer all 0.7.0+dfsg1-3 [18.6 kB] Get: 93 http://deb.debian.org/debian unstable/main amd64 pybuild-plugin-pyproject all 6.20250108 [11.6 kB] Get: 94 http://deb.debian.org/debian unstable/main amd64 python-babel-localedata all 2.16.0-1 [5696 kB] Get: 95 http://deb.debian.org/debian unstable/main amd64 python3-aiohappyeyeballs all 2.4.4-2 [13.4 kB] Get: 96 http://deb.debian.org/debian unstable/main amd64 python3-idna all 3.8-2 [41.6 kB] Get: 97 http://deb.debian.org/debian unstable/main amd64 python3-multidict amd64 6.1.0-1+b1 [39.8 kB] Get: 98 http://deb.debian.org/debian unstable/main amd64 python3-yarl amd64 1.13.1-1+b1 [118 kB] Get: 99 http://deb.debian.org/debian unstable/main amd64 python3-async-timeout all 5.0.1-1 [8324 B] Get: 100 http://deb.debian.org/debian unstable/main amd64 python3-frozenlist amd64 1.5.0-1+b1 [58.6 kB] Get: 101 http://deb.debian.org/debian unstable/main amd64 python3-aiosignal all 1.3.2-1 [6100 B] Get: 102 http://deb.debian.org/debian unstable/main amd64 python3-attr all 24.2.0-1 [68.4 kB] Get: 103 http://deb.debian.org/debian unstable/main amd64 python3-aiohttp amd64 3.10.11-1 [368 kB] Get: 104 http://deb.debian.org/debian unstable/main amd64 python3-alabaster all 0.7.16-0.1 [27.9 kB] Get: 105 http://deb.debian.org/debian unstable/main amd64 python3.12 amd64 3.12.8-4 [677 kB] Get: 106 http://deb.debian.org/debian unstable/main amd64 python3-all amd64 3.13.1-2 [1056 B] Get: 107 http://deb.debian.org/debian unstable/main amd64 python3-sniffio all 1.3.1-1 [7120 B] Get: 108 http://deb.debian.org/debian unstable/main amd64 python3-anyio all 4.7.0-1 [61.8 kB] Get: 109 http://deb.debian.org/debian unstable/main amd64 python3-babel all 2.16.0-1 [114 kB] Get: 110 http://deb.debian.org/debian unstable/main amd64 python3-blinker all 1.9.0-1 [12.6 kB] Get: 111 http://deb.debian.org/debian unstable/main amd64 python3-brotli amd64 1.1.0-2+b6 [321 kB] Get: 112 http://deb.debian.org/debian unstable/main amd64 python3-cffi-backend amd64 1.17.1-2+b1 [96.2 kB] Get: 113 http://deb.debian.org/debian unstable/main amd64 python3-brotlicffi amd64 1.1.0.0+ds1-1 [18.5 kB] Get: 114 http://deb.debian.org/debian unstable/main amd64 python3-certifi all 2024.12.14+ds-1 [9624 B] Get: 115 http://deb.debian.org/debian unstable/main amd64 python3-chardet all 5.2.0+dfsg-1 [107 kB] Get: 116 http://deb.debian.org/debian unstable/main amd64 python3-charset-normalizer amd64 3.4.0-1+b1 [140 kB] Get: 117 http://deb.debian.org/debian unstable/main amd64 python3-click all 8.1.8-1 [95.2 kB] Get: 118 http://deb.debian.org/debian unstable/main amd64 python3-coverage amd64 7.6.0+dfsg1-2+b1 [177 kB] Get: 119 http://deb.debian.org/debian unstable/main amd64 python3-decorator all 5.1.1-5 [15.1 kB] Get: 120 http://deb.debian.org/debian unstable/main amd64 python3-defusedxml all 0.7.1-3 [43.4 kB] Get: 121 http://deb.debian.org/debian unstable/main amd64 python3-roman all 4.2-1 [10.4 kB] Get: 122 http://deb.debian.org/debian unstable/main amd64 python3-docutils all 0.21.2+dfsg-2 [403 kB] Get: 123 http://deb.debian.org/debian unstable/main amd64 python3-itsdangerous all 2.2.0-1 [18.0 kB] Get: 124 http://deb.debian.org/debian unstable/main amd64 python3-markupsafe amd64 2.1.5-1+b2 [13.9 kB] Get: 125 http://deb.debian.org/debian unstable/main amd64 python3-jinja2 all 3.1.3-2 [120 kB] Get: 126 http://deb.debian.org/debian unstable/main amd64 python3-werkzeug all 3.1.3-2 [207 kB] Get: 127 http://deb.debian.org/debian unstable/main amd64 python3-flask all 3.1.0-2 [106 kB] Get: 128 http://deb.debian.org/debian unstable/main amd64 python3-rpds-py amd64 0.21.0-2 [287 kB] Get: 129 http://deb.debian.org/debian unstable/main amd64 python3-referencing all 0.35.1-2 [23.5 kB] Get: 130 http://deb.debian.org/debian unstable/main amd64 python3-jsonschema-specifications all 2023.12.1-2 [9020 B] Get: 131 http://deb.debian.org/debian unstable/main amd64 python3-jsonschema all 4.19.2-6 [71.4 kB] Get: 132 http://deb.debian.org/debian unstable/main amd64 python3-mistune all 3.0.2-2 [33.2 kB] Get: 133 http://deb.debian.org/debian unstable/main amd64 python3-yaml amd64 6.0.2-1+b1 [178 kB] Get: 134 http://deb.debian.org/debian unstable/main amd64 python3-flasgger all 0.9.7.2~dev2+dfsg-3 [1625 kB] Get: 135 http://deb.debian.org/debian unstable/main amd64 python3-orderedmultidict all 1.0.1-1.1 [11.5 kB] Get: 136 http://deb.debian.org/debian unstable/main amd64 python3-six all 1.17.0-1 [16.5 kB] Get: 137 http://deb.debian.org/debian unstable/main amd64 python3-furl all 2.1.2-1.1 [21.8 kB] Get: 138 http://deb.debian.org/debian unstable/main amd64 python3-greenlet amd64 3.1.0-1+b1 [179 kB] Get: 139 http://deb.debian.org/debian unstable/main amd64 python3-h11 all 0.14.0-1 [50.1 kB] Get: 140 http://deb.debian.org/debian unstable/main amd64 python3-pathspec all 0.12.1-1 [28.1 kB] Get: 141 http://deb.debian.org/debian unstable/main amd64 python3-pluggy all 1.5.0-1 [26.9 kB] Get: 142 http://deb.debian.org/debian unstable/main amd64 python3-trove-classifiers all 2024.9.12-1 [10.2 kB] Get: 143 http://deb.debian.org/debian unstable/main amd64 python3-hatchling all 1.27.0-1 [47.0 kB] Get: 144 http://deb.debian.org/debian unstable/main amd64 python3-httpbin all 0.10.2+dfsg-2 [89.8 kB] Get: 145 http://deb.debian.org/debian unstable/main amd64 python3-httpcore all 1.0.7-1 [44.7 kB] Get: 146 http://deb.debian.org/debian unstable/main amd64 python3-pygments all 2.18.0+dfsg-1 [836 kB] Get: 147 http://deb.debian.org/debian unstable/main amd64 python3-mdurl all 0.1.2-1 [9444 B] Get: 148 http://deb.debian.org/debian unstable/main amd64 python3-markdown-it all 3.0.0-2 [62.5 kB] Get: 149 http://deb.debian.org/debian unstable/main amd64 python3-rich all 13.9.4-1 [203 kB] Get: 150 http://deb.debian.org/debian unstable/main amd64 python3-httpx all 0.27.2-1 [77.6 kB] Get: 151 http://deb.debian.org/debian unstable/main amd64 python3-imagesize all 1.4.1-1 [6688 B] Get: 152 http://deb.debian.org/debian unstable/main amd64 python3-iniconfig all 1.1.1-2 [6396 B] Get: 153 http://deb.debian.org/debian unstable/main amd64 python3-pytest all 8.3.4-1 [250 kB] Get: 154 http://deb.debian.org/debian unstable/main amd64 python3-pytest-cov all 5.0.0-1 [26.8 kB] Get: 155 http://deb.debian.org/debian unstable/main amd64 python3-pytest-httpbin all 2.1.0-1 [14.2 kB] Get: 156 http://deb.debian.org/debian unstable/main amd64 python3-urllib3 all 2.2.3-4 [112 kB] Get: 157 http://deb.debian.org/debian unstable/main amd64 python3-requests all 2.32.3+dfsg-1 [71.9 kB] Get: 158 http://deb.debian.org/debian unstable/main amd64 python3-snowballstemmer all 2.2.0-4 [58.0 kB] Get: 159 http://deb.debian.org/debian unstable/main amd64 sphinx-common all 8.1.3-4 [616 kB] Get: 160 http://deb.debian.org/debian unstable/main amd64 python3-sphinx all 8.1.3-4 [468 kB] Get: 161 http://deb.debian.org/debian unstable/main amd64 sphinx-rtd-theme-common all 3.0.2+dfsg-1 [1023 kB] Get: 162 http://deb.debian.org/debian unstable/main amd64 python3-sphinxcontrib.jquery all 4.1-5 [7348 B] Get: 163 http://deb.debian.org/debian unstable/main amd64 python3-sphinx-rtd-theme all 3.0.2+dfsg-1 [29.5 kB] Get: 164 http://deb.debian.org/debian unstable/main amd64 python3-xmltodict all 0.13.0-1 [16.7 kB] Fetched 56.1 MB in 5s (10.8 MB/s) Preconfiguring packages ... Selecting previously unselected package fonts-lato. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 19848 files and directories currently installed.) Preparing to unpack .../fonts-lato_2.015-1_all.deb ... Unpacking fonts-lato (2.015-1) ... Selecting previously unselected package libpython3.13-minimal:amd64. Preparing to unpack .../libpython3.13-minimal_3.13.1-3_amd64.deb ... Unpacking libpython3.13-minimal:amd64 (3.13.1-3) ... Selecting previously unselected package libexpat1:amd64. Preparing to unpack .../libexpat1_2.6.4-1_amd64.deb ... Unpacking libexpat1:amd64 (2.6.4-1) ... Selecting previously unselected package python3.13-minimal. Preparing to unpack .../python3.13-minimal_3.13.1-3_amd64.deb ... Unpacking python3.13-minimal (3.13.1-3) ... Setting up libpython3.13-minimal:amd64 (3.13.1-3) ... Setting up libexpat1:amd64 (2.6.4-1) ... Setting up python3.13-minimal (3.13.1-3) ... Selecting previously unselected package python3-minimal. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 20208 files and directories currently installed.) Preparing to unpack .../0-python3-minimal_3.13.1-2_amd64.deb ... Unpacking python3-minimal (3.13.1-2) ... Selecting previously unselected package media-types. Preparing to unpack .../1-media-types_10.1.0_all.deb ... Unpacking media-types (10.1.0) ... Selecting previously unselected package netbase. Preparing to unpack .../2-netbase_6.4_all.deb ... Unpacking netbase (6.4) ... Selecting previously unselected package tzdata. Preparing to unpack .../3-tzdata_2024b-5_all.deb ... Unpacking tzdata (2024b-5) ... Selecting previously unselected package libffi8:amd64. Preparing to unpack .../4-libffi8_3.4.6-1_amd64.deb ... Unpacking libffi8:amd64 (3.4.6-1) ... Selecting previously unselected package readline-common. Preparing to unpack .../5-readline-common_8.2-6_all.deb ... Unpacking readline-common (8.2-6) ... Selecting previously unselected package libreadline8t64:amd64. Preparing to unpack .../6-libreadline8t64_8.2-6_amd64.deb ... Adding 'diversion of /lib/x86_64-linux-gnu/libhistory.so.8 to /lib/x86_64-linux-gnu/libhistory.so.8.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/x86_64-linux-gnu/libhistory.so.8.2 to /lib/x86_64-linux-gnu/libhistory.so.8.2.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/x86_64-linux-gnu/libreadline.so.8 to /lib/x86_64-linux-gnu/libreadline.so.8.usr-is-merged by libreadline8t64' Adding 'diversion of /lib/x86_64-linux-gnu/libreadline.so.8.2 to /lib/x86_64-linux-gnu/libreadline.so.8.2.usr-is-merged by libreadline8t64' Unpacking libreadline8t64:amd64 (8.2-6) ... Selecting previously unselected package libpython3.13-stdlib:amd64. Preparing to unpack .../7-libpython3.13-stdlib_3.13.1-3_amd64.deb ... Unpacking libpython3.13-stdlib:amd64 (3.13.1-3) ... Selecting previously unselected package python3.13. Preparing to unpack .../8-python3.13_3.13.1-3_amd64.deb ... Unpacking python3.13 (3.13.1-3) ... Selecting previously unselected package libpython3-stdlib:amd64. Preparing to unpack .../9-libpython3-stdlib_3.13.1-2_amd64.deb ... Unpacking libpython3-stdlib:amd64 (3.13.1-2) ... Setting up python3-minimal (3.13.1-2) ... Selecting previously unselected package python3. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 21218 files and directories currently installed.) Preparing to unpack .../000-python3_3.13.1-2_amd64.deb ... Unpacking python3 (3.13.1-2) ... Selecting previously unselected package libpython3.12-minimal:amd64. Preparing to unpack .../001-libpython3.12-minimal_3.12.8-4_amd64.deb ... Unpacking libpython3.12-minimal:amd64 (3.12.8-4) ... Selecting previously unselected package python3.12-minimal. Preparing to unpack .../002-python3.12-minimal_3.12.8-4_amd64.deb ... Unpacking python3.12-minimal (3.12.8-4) ... Selecting previously unselected package sgml-base. Preparing to unpack .../003-sgml-base_1.31_all.deb ... Unpacking sgml-base (1.31) ... Selecting previously unselected package sensible-utils. Preparing to unpack .../004-sensible-utils_0.0.24_all.deb ... Unpacking sensible-utils (0.0.24) ... Selecting previously unselected package openssl. Preparing to unpack .../005-openssl_3.4.0-2_amd64.deb ... Unpacking openssl (3.4.0-2) ... Selecting previously unselected package ca-certificates. Preparing to unpack .../006-ca-certificates_20241223_all.deb ... Unpacking ca-certificates (20241223) ... Selecting previously unselected package libmagic-mgc. Preparing to unpack .../007-libmagic-mgc_1%3a5.45-3+b1_amd64.deb ... Unpacking libmagic-mgc (1:5.45-3+b1) ... Selecting previously unselected package libmagic1t64:amd64. Preparing to unpack .../008-libmagic1t64_1%3a5.45-3+b1_amd64.deb ... Unpacking libmagic1t64:amd64 (1:5.45-3+b1) ... Selecting previously unselected package file. Preparing to unpack .../009-file_1%3a5.45-3+b1_amd64.deb ... Unpacking file (1:5.45-3+b1) ... Selecting previously unselected package gettext-base. Preparing to unpack .../010-gettext-base_0.22.5-4_amd64.deb ... Unpacking gettext-base (0.22.5-4) ... Selecting previously unselected package libuchardet0:amd64. Preparing to unpack .../011-libuchardet0_0.0.8-1+b2_amd64.deb ... Unpacking libuchardet0:amd64 (0.0.8-1+b2) ... Selecting previously unselected package groff-base. Preparing to unpack .../012-groff-base_1.23.0-7_amd64.deb ... Unpacking groff-base (1.23.0-7) ... Selecting previously unselected package bsdextrautils. Preparing to unpack .../013-bsdextrautils_2.40.2-14_amd64.deb ... Unpacking bsdextrautils (2.40.2-14) ... Selecting previously unselected package libpipeline1:amd64. Preparing to unpack .../014-libpipeline1_1.5.8-1_amd64.deb ... Unpacking libpipeline1:amd64 (1.5.8-1) ... Selecting previously unselected package man-db. Preparing to unpack .../015-man-db_2.13.0-1_amd64.deb ... Unpacking man-db (2.13.0-1) ... Selecting previously unselected package m4. Preparing to unpack .../016-m4_1.4.19-5_amd64.deb ... Unpacking m4 (1.4.19-5) ... Selecting previously unselected package autoconf. Preparing to unpack .../017-autoconf_2.72-3_all.deb ... Unpacking autoconf (2.72-3) ... Selecting previously unselected package autotools-dev. Preparing to unpack .../018-autotools-dev_20220109.1_all.deb ... Unpacking autotools-dev (20220109.1) ... Selecting previously unselected package automake. Preparing to unpack .../019-automake_1%3a1.16.5-1.3_all.deb ... Unpacking automake (1:1.16.5-1.3) ... Selecting previously unselected package autopoint. Preparing to unpack .../020-autopoint_0.22.5-4_all.deb ... Unpacking autopoint (0.22.5-4) ... Selecting previously unselected package libdebhelper-perl. Preparing to unpack .../021-libdebhelper-perl_13.23_all.deb ... Unpacking libdebhelper-perl (13.23) ... Selecting previously unselected package libtool. Preparing to unpack .../022-libtool_2.5.4-2_all.deb ... Unpacking libtool (2.5.4-2) ... Selecting previously unselected package dh-autoreconf. Preparing to unpack .../023-dh-autoreconf_20_all.deb ... Unpacking dh-autoreconf (20) ... Selecting previously unselected package libarchive-zip-perl. Preparing to unpack .../024-libarchive-zip-perl_1.68-1_all.deb ... Unpacking libarchive-zip-perl (1.68-1) ... Selecting previously unselected package libfile-stripnondeterminism-perl. Preparing to unpack .../025-libfile-stripnondeterminism-perl_1.14.0-1_all.deb ... Unpacking libfile-stripnondeterminism-perl (1.14.0-1) ... Selecting previously unselected package dh-strip-nondeterminism. Preparing to unpack .../026-dh-strip-nondeterminism_1.14.0-1_all.deb ... Unpacking dh-strip-nondeterminism (1.14.0-1) ... Selecting previously unselected package libelf1t64:amd64. Preparing to unpack .../027-libelf1t64_0.192-4_amd64.deb ... Unpacking libelf1t64:amd64 (0.192-4) ... Selecting previously unselected package dwz. Preparing to unpack .../028-dwz_0.15-1+b1_amd64.deb ... Unpacking dwz (0.15-1+b1) ... Selecting previously unselected package libunistring5:amd64. Preparing to unpack .../029-libunistring5_1.3-1_amd64.deb ... Unpacking libunistring5:amd64 (1.3-1) ... Selecting previously unselected package libicu72:amd64. Preparing to unpack .../030-libicu72_72.1-6_amd64.deb ... Unpacking libicu72:amd64 (72.1-6) ... Selecting previously unselected package libxml2:amd64. Preparing to unpack .../031-libxml2_2.12.7+dfsg+really2.9.14-0.2+b1_amd64.deb ... Unpacking libxml2:amd64 (2.12.7+dfsg+really2.9.14-0.2+b1) ... Selecting previously unselected package gettext. Preparing to unpack .../032-gettext_0.22.5-4_amd64.deb ... Unpacking gettext (0.22.5-4) ... Selecting previously unselected package intltool-debian. Preparing to unpack .../033-intltool-debian_0.35.0+20060710.6_all.deb ... Unpacking intltool-debian (0.35.0+20060710.6) ... Selecting previously unselected package po-debconf. Preparing to unpack .../034-po-debconf_1.0.21+nmu1_all.deb ... Unpacking po-debconf (1.0.21+nmu1) ... Selecting previously unselected package debhelper. Preparing to unpack .../035-debhelper_13.23_all.deb ... Unpacking debhelper (13.23) ... Selecting previously unselected package python3-autocommand. Preparing to unpack .../036-python3-autocommand_2.2.2-3_all.deb ... Unpacking python3-autocommand (2.2.2-3) ... Selecting previously unselected package python3-more-itertools. Preparing to unpack .../037-python3-more-itertools_10.5.0-1_all.deb ... Unpacking python3-more-itertools (10.5.0-1) ... Selecting previously unselected package python3-typing-extensions. Preparing to unpack .../038-python3-typing-extensions_4.12.2-2_all.deb ... Unpacking python3-typing-extensions (4.12.2-2) ... Selecting previously unselected package python3-typeguard. Preparing to unpack .../039-python3-typeguard_4.4.1-1_all.deb ... Unpacking python3-typeguard (4.4.1-1) ... Selecting previously unselected package python3-inflect. Preparing to unpack .../040-python3-inflect_7.3.1-2_all.deb ... Unpacking python3-inflect (7.3.1-2) ... Selecting previously unselected package python3-jaraco.context. Preparing to unpack .../041-python3-jaraco.context_6.0.0-1_all.deb ... Unpacking python3-jaraco.context (6.0.0-1) ... Selecting previously unselected package python3-jaraco.functools. Preparing to unpack .../042-python3-jaraco.functools_4.1.0-1_all.deb ... Unpacking python3-jaraco.functools (4.1.0-1) ... Selecting previously unselected package python3-pkg-resources. Preparing to unpack .../043-python3-pkg-resources_75.6.0-1_all.deb ... Unpacking python3-pkg-resources (75.6.0-1) ... Selecting previously unselected package python3-jaraco.text. Preparing to unpack .../044-python3-jaraco.text_4.0.0-1_all.deb ... Unpacking python3-jaraco.text (4.0.0-1) ... Selecting previously unselected package python3-zipp. Preparing to unpack .../045-python3-zipp_3.21.0-1_all.deb ... Unpacking python3-zipp (3.21.0-1) ... Selecting previously unselected package python3-setuptools. Preparing to unpack .../046-python3-setuptools_75.6.0-1_all.deb ... Unpacking python3-setuptools (75.6.0-1) ... Selecting previously unselected package dh-python. Preparing to unpack .../047-dh-python_6.20250108_all.deb ... Unpacking dh-python (6.20250108) ... Selecting previously unselected package xml-core. Preparing to unpack .../048-xml-core_0.19_all.deb ... Unpacking xml-core (0.19) ... Selecting previously unselected package docutils-common. Preparing to unpack .../049-docutils-common_0.21.2+dfsg-2_all.deb ... Unpacking docutils-common (0.21.2+dfsg-2) ... Selecting previously unselected package fonts-font-awesome. Preparing to unpack .../050-fonts-font-awesome_5.0.10+really4.7.0~dfsg-4.1_all.deb ... Unpacking fonts-font-awesome (5.0.10+really4.7.0~dfsg-4.1) ... Selecting previously unselected package libbrotli1:amd64. Preparing to unpack .../051-libbrotli1_1.1.0-2+b6_amd64.deb ... Unpacking libbrotli1:amd64 (1.1.0-2+b6) ... Selecting previously unselected package libcom-err2:amd64. Preparing to unpack .../052-libcom-err2_1.47.2-1_amd64.deb ... Unpacking libcom-err2:amd64 (1.47.2-1) ... Selecting previously unselected package libkrb5support0:amd64. Preparing to unpack .../053-libkrb5support0_1.21.3-3_amd64.deb ... Unpacking libkrb5support0:amd64 (1.21.3-3) ... Selecting previously unselected package libk5crypto3:amd64. Preparing to unpack .../054-libk5crypto3_1.21.3-3_amd64.deb ... Unpacking libk5crypto3:amd64 (1.21.3-3) ... Selecting previously unselected package libkeyutils1:amd64. Preparing to unpack .../055-libkeyutils1_1.6.3-4_amd64.deb ... Unpacking libkeyutils1:amd64 (1.6.3-4) ... Selecting previously unselected package libkrb5-3:amd64. Preparing to unpack .../056-libkrb5-3_1.21.3-3_amd64.deb ... Unpacking libkrb5-3:amd64 (1.21.3-3) ... Selecting previously unselected package libgssapi-krb5-2:amd64. Preparing to unpack .../057-libgssapi-krb5-2_1.21.3-3_amd64.deb ... Unpacking libgssapi-krb5-2:amd64 (1.21.3-3) ... Selecting previously unselected package libjs-jquery. Preparing to unpack .../058-libjs-jquery_3.6.1+dfsg+~3.5.14-1_all.deb ... Unpacking libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... Selecting previously unselected package libjs-jquery-hotkeys. Preparing to unpack .../059-libjs-jquery-hotkeys_0.2.0-1_all.deb ... Unpacking libjs-jquery-hotkeys (0.2.0-1) ... Selecting previously unselected package libjs-jquery-isonscreen. Preparing to unpack .../060-libjs-jquery-isonscreen_1.2.0-1.1_all.deb ... Unpacking libjs-jquery-isonscreen (1.2.0-1.1) ... Selecting previously unselected package libjs-jquery-metadata. Preparing to unpack .../061-libjs-jquery-metadata_12-4_all.deb ... Unpacking libjs-jquery-metadata (12-4) ... Selecting previously unselected package libjs-jquery-tablesorter. Preparing to unpack .../062-libjs-jquery-tablesorter_1%3a2.31.3+dfsg1-4_all.deb ... Unpacking libjs-jquery-tablesorter (1:2.31.3+dfsg1-4) ... Selecting previously unselected package libjs-jquery-throttle-debounce. Preparing to unpack .../063-libjs-jquery-throttle-debounce_1.1+dfsg.1-2_all.deb ... Unpacking libjs-jquery-throttle-debounce (1.1+dfsg.1-2) ... Selecting previously unselected package libjs-underscore. Preparing to unpack .../064-libjs-underscore_1.13.4~dfsg+~1.11.4-3_all.deb ... Unpacking libjs-underscore (1.13.4~dfsg+~1.11.4-3) ... Selecting previously unselected package libjs-sphinxdoc. Preparing to unpack .../065-libjs-sphinxdoc_8.1.3-4_all.deb ... Unpacking libjs-sphinxdoc (8.1.3-4) ... Selecting previously unselected package libjson-perl. Preparing to unpack .../066-libjson-perl_4.10000-1_all.deb ... Unpacking libjson-perl (4.10000-1) ... Selecting previously unselected package libtirpc-common. Preparing to unpack .../067-libtirpc-common_1.3.4+ds-1.3_all.deb ... Unpacking libtirpc-common (1.3.4+ds-1.3) ... Selecting previously unselected package libtirpc3t64:amd64. Preparing to unpack .../068-libtirpc3t64_1.3.4+ds-1.3+b1_amd64.deb ... Adding 'diversion of /lib/x86_64-linux-gnu/libtirpc.so.3 to /lib/x86_64-linux-gnu/libtirpc.so.3.usr-is-merged by libtirpc3t64' Adding 'diversion of /lib/x86_64-linux-gnu/libtirpc.so.3.0.0 to /lib/x86_64-linux-gnu/libtirpc.so.3.0.0.usr-is-merged by libtirpc3t64' Unpacking libtirpc3t64:amd64 (1.3.4+ds-1.3+b1) ... Selecting previously unselected package libnsl2:amd64. Preparing to unpack .../069-libnsl2_1.3.0-3+b3_amd64.deb ... Unpacking libnsl2:amd64 (1.3.0-3+b3) ... Selecting previously unselected package libpython3.12-stdlib:amd64. Preparing to unpack .../070-libpython3.12-stdlib_3.12.8-4_amd64.deb ... Unpacking libpython3.12-stdlib:amd64 (3.12.8-4) ... Selecting previously unselected package libyaml-0-2:amd64. Preparing to unpack .../071-libyaml-0-2_0.2.5-2_amd64.deb ... Unpacking libyaml-0-2:amd64 (0.2.5-2) ... Selecting previously unselected package python3-packaging. Preparing to unpack .../072-python3-packaging_24.2-1_all.deb ... Unpacking python3-packaging (24.2-1) ... Selecting previously unselected package python3-pyproject-hooks. Preparing to unpack .../073-python3-pyproject-hooks_1.2.0-1_all.deb ... Unpacking python3-pyproject-hooks (1.2.0-1) ... Selecting previously unselected package python3-toml. Preparing to unpack .../074-python3-toml_0.10.2-1_all.deb ... Unpacking python3-toml (0.10.2-1) ... Selecting previously unselected package python3-wheel. Preparing to unpack .../075-python3-wheel_0.45.1-1_all.deb ... Unpacking python3-wheel (0.45.1-1) ... Selecting previously unselected package python3-build. Preparing to unpack .../076-python3-build_1.2.2-1_all.deb ... Unpacking python3-build (1.2.2-1) ... Selecting previously unselected package python3-installer. Preparing to unpack .../077-python3-installer_0.7.0+dfsg1-3_all.deb ... Unpacking python3-installer (0.7.0+dfsg1-3) ... Selecting previously unselected package pybuild-plugin-pyproject. Preparing to unpack .../078-pybuild-plugin-pyproject_6.20250108_all.deb ... Unpacking pybuild-plugin-pyproject (6.20250108) ... Selecting previously unselected package python-babel-localedata. Preparing to unpack .../079-python-babel-localedata_2.16.0-1_all.deb ... Unpacking python-babel-localedata (2.16.0-1) ... Selecting previously unselected package python3-aiohappyeyeballs. Preparing to unpack .../080-python3-aiohappyeyeballs_2.4.4-2_all.deb ... Unpacking python3-aiohappyeyeballs (2.4.4-2) ... Selecting previously unselected package python3-idna. Preparing to unpack .../081-python3-idna_3.8-2_all.deb ... Unpacking python3-idna (3.8-2) ... Selecting previously unselected package python3-multidict. Preparing to unpack .../082-python3-multidict_6.1.0-1+b1_amd64.deb ... Unpacking python3-multidict (6.1.0-1+b1) ... Selecting previously unselected package python3-yarl. Preparing to unpack .../083-python3-yarl_1.13.1-1+b1_amd64.deb ... Unpacking python3-yarl (1.13.1-1+b1) ... Selecting previously unselected package python3-async-timeout. Preparing to unpack .../084-python3-async-timeout_5.0.1-1_all.deb ... Unpacking python3-async-timeout (5.0.1-1) ... Selecting previously unselected package python3-frozenlist. Preparing to unpack .../085-python3-frozenlist_1.5.0-1+b1_amd64.deb ... Unpacking python3-frozenlist (1.5.0-1+b1) ... Selecting previously unselected package python3-aiosignal. Preparing to unpack .../086-python3-aiosignal_1.3.2-1_all.deb ... Unpacking python3-aiosignal (1.3.2-1) ... Selecting previously unselected package python3-attr. Preparing to unpack .../087-python3-attr_24.2.0-1_all.deb ... Unpacking python3-attr (24.2.0-1) ... Selecting previously unselected package python3-aiohttp. Preparing to unpack .../088-python3-aiohttp_3.10.11-1_amd64.deb ... Unpacking python3-aiohttp (3.10.11-1) ... Selecting previously unselected package python3-alabaster. Preparing to unpack .../089-python3-alabaster_0.7.16-0.1_all.deb ... Unpacking python3-alabaster (0.7.16-0.1) ... Selecting previously unselected package python3.12. Preparing to unpack .../090-python3.12_3.12.8-4_amd64.deb ... Unpacking python3.12 (3.12.8-4) ... Selecting previously unselected package python3-all. Preparing to unpack .../091-python3-all_3.13.1-2_amd64.deb ... Unpacking python3-all (3.13.1-2) ... Selecting previously unselected package python3-sniffio. Preparing to unpack .../092-python3-sniffio_1.3.1-1_all.deb ... Unpacking python3-sniffio (1.3.1-1) ... Selecting previously unselected package python3-anyio. Preparing to unpack .../093-python3-anyio_4.7.0-1_all.deb ... Unpacking python3-anyio (4.7.0-1) ... Selecting previously unselected package python3-babel. Preparing to unpack .../094-python3-babel_2.16.0-1_all.deb ... Unpacking python3-babel (2.16.0-1) ... Selecting previously unselected package python3-blinker. Preparing to unpack .../095-python3-blinker_1.9.0-1_all.deb ... Unpacking python3-blinker (1.9.0-1) ... Selecting previously unselected package python3-brotli. Preparing to unpack .../096-python3-brotli_1.1.0-2+b6_amd64.deb ... Unpacking python3-brotli (1.1.0-2+b6) ... Selecting previously unselected package python3-cffi-backend:amd64. Preparing to unpack .../097-python3-cffi-backend_1.17.1-2+b1_amd64.deb ... Unpacking python3-cffi-backend:amd64 (1.17.1-2+b1) ... Selecting previously unselected package python3-brotlicffi. Preparing to unpack .../098-python3-brotlicffi_1.1.0.0+ds1-1_amd64.deb ... Unpacking python3-brotlicffi (1.1.0.0+ds1-1) ... Selecting previously unselected package python3-certifi. Preparing to unpack .../099-python3-certifi_2024.12.14+ds-1_all.deb ... Unpacking python3-certifi (2024.12.14+ds-1) ... Selecting previously unselected package python3-chardet. Preparing to unpack .../100-python3-chardet_5.2.0+dfsg-1_all.deb ... Unpacking python3-chardet (5.2.0+dfsg-1) ... Selecting previously unselected package python3-charset-normalizer. Preparing to unpack .../101-python3-charset-normalizer_3.4.0-1+b1_amd64.deb ... Unpacking python3-charset-normalizer (3.4.0-1+b1) ... Selecting previously unselected package python3-click. Preparing to unpack .../102-python3-click_8.1.8-1_all.deb ... Unpacking python3-click (8.1.8-1) ... Selecting previously unselected package python3-coverage. Preparing to unpack .../103-python3-coverage_7.6.0+dfsg1-2+b1_amd64.deb ... Unpacking python3-coverage (7.6.0+dfsg1-2+b1) ... Selecting previously unselected package python3-decorator. Preparing to unpack .../104-python3-decorator_5.1.1-5_all.deb ... Unpacking python3-decorator (5.1.1-5) ... Selecting previously unselected package python3-defusedxml. Preparing to unpack .../105-python3-defusedxml_0.7.1-3_all.deb ... Unpacking python3-defusedxml (0.7.1-3) ... Selecting previously unselected package python3-roman. Preparing to unpack .../106-python3-roman_4.2-1_all.deb ... Unpacking python3-roman (4.2-1) ... Selecting previously unselected package python3-docutils. Preparing to unpack .../107-python3-docutils_0.21.2+dfsg-2_all.deb ... Unpacking python3-docutils (0.21.2+dfsg-2) ... Selecting previously unselected package python3-itsdangerous. Preparing to unpack .../108-python3-itsdangerous_2.2.0-1_all.deb ... Unpacking python3-itsdangerous (2.2.0-1) ... Selecting previously unselected package python3-markupsafe. Preparing to unpack .../109-python3-markupsafe_2.1.5-1+b2_amd64.deb ... Unpacking python3-markupsafe (2.1.5-1+b2) ... Selecting previously unselected package python3-jinja2. Preparing to unpack .../110-python3-jinja2_3.1.3-2_all.deb ... Unpacking python3-jinja2 (3.1.3-2) ... Selecting previously unselected package python3-werkzeug. Preparing to unpack .../111-python3-werkzeug_3.1.3-2_all.deb ... Unpacking python3-werkzeug (3.1.3-2) ... Selecting previously unselected package python3-flask. Preparing to unpack .../112-python3-flask_3.1.0-2_all.deb ... Unpacking python3-flask (3.1.0-2) ... Selecting previously unselected package python3-rpds-py. Preparing to unpack .../113-python3-rpds-py_0.21.0-2_amd64.deb ... Unpacking python3-rpds-py (0.21.0-2) ... Selecting previously unselected package python3-referencing. Preparing to unpack .../114-python3-referencing_0.35.1-2_all.deb ... Unpacking python3-referencing (0.35.1-2) ... Selecting previously unselected package python3-jsonschema-specifications. Preparing to unpack .../115-python3-jsonschema-specifications_2023.12.1-2_all.deb ... Unpacking python3-jsonschema-specifications (2023.12.1-2) ... Selecting previously unselected package python3-jsonschema. Preparing to unpack .../116-python3-jsonschema_4.19.2-6_all.deb ... Unpacking python3-jsonschema (4.19.2-6) ... Selecting previously unselected package python3-mistune. Preparing to unpack .../117-python3-mistune_3.0.2-2_all.deb ... Unpacking python3-mistune (3.0.2-2) ... Selecting previously unselected package python3-yaml. Preparing to unpack .../118-python3-yaml_6.0.2-1+b1_amd64.deb ... Unpacking python3-yaml (6.0.2-1+b1) ... Selecting previously unselected package python3-flasgger. Preparing to unpack .../119-python3-flasgger_0.9.7.2~dev2+dfsg-3_all.deb ... Unpacking python3-flasgger (0.9.7.2~dev2+dfsg-3) ... Selecting previously unselected package python3-orderedmultidict. Preparing to unpack .../120-python3-orderedmultidict_1.0.1-1.1_all.deb ... Unpacking python3-orderedmultidict (1.0.1-1.1) ... Selecting previously unselected package python3-six. Preparing to unpack .../121-python3-six_1.17.0-1_all.deb ... Unpacking python3-six (1.17.0-1) ... Selecting previously unselected package python3-furl. Preparing to unpack .../122-python3-furl_2.1.2-1.1_all.deb ... Unpacking python3-furl (2.1.2-1.1) ... Selecting previously unselected package python3-greenlet. Preparing to unpack .../123-python3-greenlet_3.1.0-1+b1_amd64.deb ... Unpacking python3-greenlet (3.1.0-1+b1) ... Selecting previously unselected package python3-h11. Preparing to unpack .../124-python3-h11_0.14.0-1_all.deb ... Unpacking python3-h11 (0.14.0-1) ... Selecting previously unselected package python3-pathspec. Preparing to unpack .../125-python3-pathspec_0.12.1-1_all.deb ... Unpacking python3-pathspec (0.12.1-1) ... Selecting previously unselected package python3-pluggy. Preparing to unpack .../126-python3-pluggy_1.5.0-1_all.deb ... Unpacking python3-pluggy (1.5.0-1) ... Selecting previously unselected package python3-trove-classifiers. Preparing to unpack .../127-python3-trove-classifiers_2024.9.12-1_all.deb ... Unpacking python3-trove-classifiers (2024.9.12-1) ... Selecting previously unselected package python3-hatchling. Preparing to unpack .../128-python3-hatchling_1.27.0-1_all.deb ... Unpacking python3-hatchling (1.27.0-1) ... Selecting previously unselected package python3-httpbin. Preparing to unpack .../129-python3-httpbin_0.10.2+dfsg-2_all.deb ... Unpacking python3-httpbin (0.10.2+dfsg-2) ... Selecting previously unselected package python3-httpcore. Preparing to unpack .../130-python3-httpcore_1.0.7-1_all.deb ... Unpacking python3-httpcore (1.0.7-1) ... Selecting previously unselected package python3-pygments. Preparing to unpack .../131-python3-pygments_2.18.0+dfsg-1_all.deb ... Unpacking python3-pygments (2.18.0+dfsg-1) ... Selecting previously unselected package python3-mdurl. Preparing to unpack .../132-python3-mdurl_0.1.2-1_all.deb ... Unpacking python3-mdurl (0.1.2-1) ... Selecting previously unselected package python3-markdown-it. Preparing to unpack .../133-python3-markdown-it_3.0.0-2_all.deb ... Unpacking python3-markdown-it (3.0.0-2) ... Selecting previously unselected package python3-rich. Preparing to unpack .../134-python3-rich_13.9.4-1_all.deb ... Unpacking python3-rich (13.9.4-1) ... Selecting previously unselected package python3-httpx. Preparing to unpack .../135-python3-httpx_0.27.2-1_all.deb ... Unpacking python3-httpx (0.27.2-1) ... Selecting previously unselected package python3-imagesize. Preparing to unpack .../136-python3-imagesize_1.4.1-1_all.deb ... Unpacking python3-imagesize (1.4.1-1) ... Selecting previously unselected package python3-iniconfig. Preparing to unpack .../137-python3-iniconfig_1.1.1-2_all.deb ... Unpacking python3-iniconfig (1.1.1-2) ... Selecting previously unselected package python3-pytest. Preparing to unpack .../138-python3-pytest_8.3.4-1_all.deb ... Unpacking python3-pytest (8.3.4-1) ... Selecting previously unselected package python3-pytest-cov. Preparing to unpack .../139-python3-pytest-cov_5.0.0-1_all.deb ... Unpacking python3-pytest-cov (5.0.0-1) ... Selecting previously unselected package python3-pytest-httpbin. Preparing to unpack .../140-python3-pytest-httpbin_2.1.0-1_all.deb ... Unpacking python3-pytest-httpbin (2.1.0-1) ... Selecting previously unselected package python3-urllib3. Preparing to unpack .../141-python3-urllib3_2.2.3-4_all.deb ... Unpacking python3-urllib3 (2.2.3-4) ... Selecting previously unselected package python3-requests. Preparing to unpack .../142-python3-requests_2.32.3+dfsg-1_all.deb ... Unpacking python3-requests (2.32.3+dfsg-1) ... Selecting previously unselected package python3-snowballstemmer. Preparing to unpack .../143-python3-snowballstemmer_2.2.0-4_all.deb ... Unpacking python3-snowballstemmer (2.2.0-4) ... Selecting previously unselected package sphinx-common. Preparing to unpack .../144-sphinx-common_8.1.3-4_all.deb ... Unpacking sphinx-common (8.1.3-4) ... Selecting previously unselected package python3-sphinx. Preparing to unpack .../145-python3-sphinx_8.1.3-4_all.deb ... Unpacking python3-sphinx (8.1.3-4) ... Selecting previously unselected package sphinx-rtd-theme-common. Preparing to unpack .../146-sphinx-rtd-theme-common_3.0.2+dfsg-1_all.deb ... Unpacking sphinx-rtd-theme-common (3.0.2+dfsg-1) ... Selecting previously unselected package python3-sphinxcontrib.jquery. Preparing to unpack .../147-python3-sphinxcontrib.jquery_4.1-5_all.deb ... Unpacking python3-sphinxcontrib.jquery (4.1-5) ... Selecting previously unselected package python3-sphinx-rtd-theme. Preparing to unpack .../148-python3-sphinx-rtd-theme_3.0.2+dfsg-1_all.deb ... Unpacking python3-sphinx-rtd-theme (3.0.2+dfsg-1) ... Selecting previously unselected package python3-xmltodict. Preparing to unpack .../149-python3-xmltodict_0.13.0-1_all.deb ... Unpacking python3-xmltodict (0.13.0-1) ... Setting up media-types (10.1.0) ... Setting up libpipeline1:amd64 (1.5.8-1) ... Setting up libkeyutils1:amd64 (1.6.3-4) ... Setting up fonts-lato (2.015-1) ... Setting up libicu72:amd64 (72.1-6) ... Setting up bsdextrautils (2.40.2-14) ... Setting up libmagic-mgc (1:5.45-3+b1) ... Setting up libarchive-zip-perl (1.68-1) ... Setting up libyaml-0-2:amd64 (0.2.5-2) ... Setting up libtirpc-common (1.3.4+ds-1.3) ... Setting up libdebhelper-perl (13.23) ... Setting up libbrotli1:amd64 (1.1.0-2+b6) ... Setting up libmagic1t64:amd64 (1:5.45-3+b1) ... Setting up libpython3.12-minimal:amd64 (3.12.8-4) ... Setting up gettext-base (0.22.5-4) ... Setting up m4 (1.4.19-5) ... Setting up libcom-err2:amd64 (1.47.2-1) ... Setting up file (1:5.45-3+b1) ... Setting up libjs-jquery-throttle-debounce (1.1+dfsg.1-2) ... Setting up libelf1t64:amd64 (0.192-4) ... Setting up python-babel-localedata (2.16.0-1) ... Setting up libkrb5support0:amd64 (1.21.3-3) ... Setting up tzdata (2024b-5) ... Current default time zone: 'Etc/UTC' Local time is now: Thu Feb 12 09:16:16 UTC 2026. Universal Time is now: Thu Feb 12 09:16:16 UTC 2026. Run 'dpkg-reconfigure tzdata' if you wish to change it. Setting up autotools-dev (20220109.1) ... Setting up libunistring5:amd64 (1.3-1) ... Setting up autopoint (0.22.5-4) ... Setting up libk5crypto3:amd64 (1.21.3-3) ... Setting up autoconf (2.72-3) ... Setting up libffi8:amd64 (3.4.6-1) ... Setting up dwz (0.15-1+b1) ... Setting up sensible-utils (0.0.24) ... Setting up libuchardet0:amd64 (0.0.8-1+b2) ... Setting up libjson-perl (4.10000-1) ... Setting up netbase (6.4) ... Setting up sgml-base (1.31) ... Setting up libkrb5-3:amd64 (1.21.3-3) ... Setting up libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... Setting up libjs-jquery-hotkeys (0.2.0-1) ... Setting up openssl (3.4.0-2) ... Setting up readline-common (8.2-6) ... Setting up libxml2:amd64 (2.12.7+dfsg+really2.9.14-0.2+b1) ... Setting up fonts-font-awesome (5.0.10+really4.7.0~dfsg-4.1) ... Setting up sphinx-rtd-theme-common (3.0.2+dfsg-1) ... Setting up libjs-underscore (1.13.4~dfsg+~1.11.4-3) ... Setting up automake (1:1.16.5-1.3) ... update-alternatives: using /usr/bin/automake-1.16 to provide /usr/bin/automake (automake) in auto mode Setting up libfile-stripnondeterminism-perl (1.14.0-1) ... Setting up python3.12-minimal (3.12.8-4) ... Setting up gettext (0.22.5-4) ... Setting up libtool (2.5.4-2) ... Setting up intltool-debian (0.35.0+20060710.6) ... Setting up dh-autoreconf (20) ... Setting up ca-certificates (20241223) ... Updating certificates in /etc/ssl/certs... 152 added, 0 removed; done. Setting up libjs-jquery-metadata (12-4) ... Setting up libjs-jquery-isonscreen (1.2.0-1.1) ... Setting up libgssapi-krb5-2:amd64 (1.21.3-3) ... Setting up libjs-sphinxdoc (8.1.3-4) ... Setting up libreadline8t64:amd64 (8.2-6) ... Setting up dh-strip-nondeterminism (1.14.0-1) ... Setting up libjs-jquery-tablesorter (1:2.31.3+dfsg1-4) ... Setting up groff-base (1.23.0-7) ... Setting up xml-core (0.19) ... Setting up libpython3.13-stdlib:amd64 (3.13.1-3) ... Setting up libpython3-stdlib:amd64 (3.13.1-2) ... Setting up libtirpc3t64:amd64 (1.3.4+ds-1.3+b1) ... Setting up python3.13 (3.13.1-3) ... Setting up po-debconf (1.0.21+nmu1) ... Setting up python3 (3.13.1-2) ... Setting up python3-zipp (3.21.0-1) ... Setting up python3-click (8.1.8-1) ... Setting up python3-autocommand (2.2.2-3) ... Setting up man-db (2.13.0-1) ... Not building database; man-db/auto-update is not 'true'. Setting up python3-markupsafe (2.1.5-1+b2) ... Setting up python3-wheel (0.45.1-1) ... Setting up python3-multidict (6.1.0-1+b1) ... Setting up python3-frozenlist (1.5.0-1+b1) ... Setting up python3-aiosignal (1.3.2-1) ... Setting up python3-async-timeout (5.0.1-1) ... Setting up python3-six (1.17.0-1) ... Setting up python3-roman (4.2-1) ... Setting up python3-decorator (5.1.1-5) ... Setting up python3-xmltodict (0.13.0-1) ... Setting up python3-jinja2 (3.1.3-2) ... Setting up python3-packaging (24.2-1) ... Setting up python3-pyproject-hooks (1.2.0-1) ... Setting up python3-certifi (2024.12.14+ds-1) ... Setting up python3-snowballstemmer (2.2.0-4) ... Setting up python3-werkzeug (3.1.3-2) ... Setting up python3-brotli (1.1.0-2+b6) ... Setting up python3-mdurl (0.1.2-1) ... Setting up sphinx-common (8.1.3-4) ... Setting up python3-greenlet (3.1.0-1+b1) ... Setting up python3-idna (3.8-2) ... Setting up python3-h11 (0.14.0-1) ... Setting up python3-typing-extensions (4.12.2-2) ... Setting up python3-aiohappyeyeballs (2.4.4-2) ... Setting up python3-toml (0.10.2-1) ... Setting up python3-installer (0.7.0+dfsg1-3) ... Setting up python3-urllib3 (2.2.3-4) ... Setting up python3-pluggy (1.5.0-1) ... Setting up python3-markdown-it (3.0.0-2) ... Setting up python3-rpds-py (0.21.0-2) ... Setting up python3-trove-classifiers (2024.9.12-1) ... Setting up libnsl2:amd64 (1.3.0-3+b3) ... Setting up python3-build (1.2.2-1) ... Setting up python3-pathspec (0.12.1-1) ... Setting up python3-yarl (1.13.1-1+b1) ... Setting up python3-mistune (3.0.2-2) ... Setting up python3-cffi-backend:amd64 (1.17.1-2+b1) ... Setting up python3-imagesize (1.4.1-1) ... Setting up python3-blinker (1.9.0-1) ... Setting up python3-more-itertools (10.5.0-1) ... Setting up python3-httpcore (1.0.7-1) ... Setting up python3-iniconfig (1.1.1-2) ... Setting up python3-sniffio (1.3.1-1) ... Setting up python3-attr (24.2.0-1) ... Setting up python3-brotlicffi (1.1.0.0+ds1-1) ... Setting up python3-orderedmultidict (1.0.1-1.1) ... Setting up python3-jaraco.functools (4.1.0-1) ... Setting up libpython3.12-stdlib:amd64 (3.12.8-4) ... Setting up python3-jaraco.context (6.0.0-1) ... Setting up python3-anyio (4.7.0-1) ... Setting up python3-defusedxml (0.7.1-3) ... Setting up python3-charset-normalizer (3.4.0-1+b1) ... Setting up python3-pytest (8.3.4-1) ... Setting up python3-alabaster (0.7.16-0.1) ... Setting up python3.12 (3.12.8-4) ... Setting up python3-typeguard (4.4.1-1) ... Setting up python3-aiohttp (3.10.11-1) ... Setting up python3-itsdangerous (2.2.0-1) ... Setting up python3-all (3.13.1-2) ... Setting up python3-coverage (7.6.0+dfsg1-2+b1) ... Setting up python3-yaml (6.0.2-1+b1) ... Setting up debhelper (13.23) ... Setting up python3-pytest-cov (5.0.0-1) ... Setting up python3-inflect (7.3.1-2) ... Setting up python3-jaraco.text (4.0.0-1) ... Setting up python3-furl (2.1.2-1.1) ... Setting up python3-hatchling (1.27.0-1) ... Setting up python3-referencing (0.35.1-2) ... Setting up python3-pkg-resources (75.6.0-1) ... Setting up python3-setuptools (75.6.0-1) ... Setting up python3-babel (2.16.0-1) ... update-alternatives: using /usr/bin/pybabel-python3 to provide /usr/bin/pybabel (pybabel) in auto mode Setting up python3-flask (3.1.0-2) ... Setting up python3-pygments (2.18.0+dfsg-1) ... Setting up python3-chardet (5.2.0+dfsg-1) ... Setting up python3-requests (2.32.3+dfsg-1) ... Setting up python3-jsonschema-specifications (2023.12.1-2) ... Setting up dh-python (6.20250108) ... Setting up python3-rich (13.9.4-1) ... Setting up pybuild-plugin-pyproject (6.20250108) ... Setting up python3-httpx (0.27.2-1) ... Setting up python3-jsonschema (4.19.2-6) ... Setting up python3-flasgger (0.9.7.2~dev2+dfsg-3) ... Setting up python3-httpbin (0.10.2+dfsg-2) ... Setting up python3-pytest-httpbin (2.1.0-1) ... Processing triggers for libc-bin (2.40-5) ... Processing triggers for sgml-base (1.31) ... Setting up docutils-common (0.21.2+dfsg-2) ... Processing triggers for sgml-base (1.31) ... Setting up python3-docutils (0.21.2+dfsg-2) ... Setting up python3-sphinx (8.1.3-4) ... Setting up python3-sphinxcontrib.jquery (4.1-5) ... Setting up python3-sphinx-rtd-theme (3.0.2+dfsg-1) ... Processing triggers for ca-certificates (20241223) ... Updating certificates in /etc/ssl/certs... 0 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. Reading package lists... Building dependency tree... Reading state information... Reading extended state information... Initializing package states... Writing extended state information... Building tag database... -> Finished parsing the build-deps I: Building the package I: user script /srv/workspace/pbuilder/263293/tmp/hooks/A99_set_merged_usr starting Not re-configuring usrmerge for unstable I: user script /srv/workspace/pbuilder/263293/tmp/hooks/A99_set_merged_usr finished hostname: Name or service not known I: Running cd /build/reproducible-path/python-pook-2.1.3/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-genchanges -S > ../python-pook_2.1.3-1_source.changes dpkg-buildpackage: info: source package python-pook dpkg-buildpackage: info: source version 2.1.3-1 dpkg-buildpackage: info: source distribution unstable dpkg-buildpackage: info: source changed by Alexandre Detiste dpkg-source --before-build . dpkg-buildpackage: info: host architecture amd64 dpkg-source: info: using options from python-pook-2.1.3/debian/source/options: --extend-diff-ignore=^[^/]*[.]egg-info/ debian/rules clean dh clean --with sphinxdoc --buildsystem=pybuild dh_auto_clean -O--buildsystem=pybuild dh_autoreconf_clean -O--buildsystem=pybuild dh_clean -O--buildsystem=pybuild debian/rules binary dh binary --with sphinxdoc --buildsystem=pybuild dh_update_autotools_config -O--buildsystem=pybuild dh_autoreconf -O--buildsystem=pybuild dh_auto_configure -O--buildsystem=pybuild dh_auto_build -O--buildsystem=pybuild I: pybuild plugin_pyproject:129: Building wheel for python3.12 with "build" module I: pybuild base:311: python3.12 -m build --skip-dependency-check --no-isolation --wheel --outdir /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook * Building wheel... Successfully built pook-2.1.3-py3-none-any.whl I: pybuild plugin_pyproject:144: Unpacking wheel built for python3.12 with "installer" module I: pybuild plugin_pyproject:129: Building wheel for python3.13 with "build" module I: pybuild base:311: python3.13 -m build --skip-dependency-check --no-isolation --wheel --outdir /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook * Building wheel... Successfully built pook-2.1.3-py3-none-any.whl I: pybuild plugin_pyproject:144: Unpacking wheel built for python3.13 with "installer" module debian/rules execute_after_dh_auto_build make[1]: Entering directory '/build/reproducible-path/python-pook-2.1.3' PYTHONPATH=src/ http_proxy='127.0.0.1:9' python3 -m sphinx -N -bhtml docs/ build/html # HTML generator Running Sphinx v8.1.3 loading translations [en]... done making output directory... done Converting `source_suffix = '.rst'` to `source_suffix = {'.rst': 'restructuredtext'}`. [autosummary] generating autosummary for: api.rst, examples.rst, faq.rst, history.rst, how_it_works.rst, index.rst, install.rst building [mo]: targets for 0 po files that are out of date writing output... building [html]: targets for 7 source files that are out of date updating environment: [new config] 7 added, 0 changed, 0 removed reading sources... [ 14%] api reading sources... [ 29%] examples reading sources... [ 43%] faq reading sources... [ 57%] history reading sources... [ 71%] how_it_works reading sources... [ 86%] index reading sources... [100%] install looking for now-outdated files... none found pickling environment... done checking consistency... done preparing documents... done copying assets... copying static files... Writing evaluated template result to /build/reproducible-path/python-pook-2.1.3/build/html/_static/documentation_options.js Writing evaluated template result to /build/reproducible-path/python-pook-2.1.3/build/html/_static/language_data.js Writing evaluated template result to /build/reproducible-path/python-pook-2.1.3/build/html/_static/basic.css Writing evaluated template result to /build/reproducible-path/python-pook-2.1.3/build/html/_static/js/versions.js copying static files: done copying extra files... copying extra files: done copying assets: done writing output... [ 14%] api writing output... [ 29%] examples writing output... [ 43%] faq writing output... [ 57%] history writing output... [ 71%] how_it_works writing output... [ 86%] index writing output... [100%] install generating indices... genindex py-modindex done highlighting module code... [ 8%] pook.api highlighting module code... [ 15%] pook.engine highlighting module code... [ 23%] pook.interceptors highlighting module code... [ 31%] pook.interceptors._httpx highlighting module code... [ 38%] pook.interceptors.aiohttp highlighting module code... [ 46%] pook.interceptors.base highlighting module code... [ 54%] pook.interceptors.http highlighting module code... [ 62%] pook.interceptors.urllib3 highlighting module code... [ 69%] pook.matcher highlighting module code... [ 77%] pook.mock highlighting module code... [ 85%] pook.mock_engine highlighting module code... [ 92%] pook.request highlighting module code... [100%] pook.response writing additional pages... search done dumping search index in English (code: en)... done dumping object inventory... done build succeeded. The HTML pages are in build/html. make[1]: Leaving directory '/build/reproducible-path/python-pook-2.1.3' debian/rules override_dh_auto_test make[1]: Entering directory '/build/reproducible-path/python-pook-2.1.3' http_proxy= dh_auto_test || true I: pybuild pybuild:308: cp -r /build/reproducible-path/python-pook-2.1.3/examples /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build ; rm -f /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/mocket_example.py I: pybuild base:311: cd /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build; python3.12 -m pytest tests ============================= test session starts ============================== platform linux -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0 rootdir: /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build configfile: pyproject.toml plugins: pook-2.1.3, httpbin-2.1.0, cov-5.0.0, typeguard-4.4.1, anyio-4.7.0 collected 232 items tests/integration/engines_test.py .. [ 0%] tests/integration/examples_test.py F.....F...F...F..F.F... [ 10%] tests/integration/pook_requests_test.py FFF [ 12%] tests/unit/api_test.py ......s [ 15%] tests/unit/engine_test.py .. [ 15%] tests/unit/exceptions_test.py . [ 16%] tests/unit/interceptors/aiohttp_test.py FFFFFFFFFFFFssssssss [ 25%] tests/unit/interceptors/httpx_test.py FFFFFFFFFFFFFFFFFFFFFFFFFsFFFF [ 37%] tests/unit/interceptors/module_test.py . [ 38%] tests/unit/interceptors/urllib3_test.py FFFFFFFFFFFFFFFFFFFFFFFF........ [ 52%] F [ 52%] tests/unit/interceptors/urllib_test.py FFFFFFFFFFFFFF [ 58%] tests/unit/matchers/base_test.py .... [ 60%] tests/unit/matchers/headers_test.py ...........FF............ [ 71%] tests/unit/matchers/query_test.py FF [ 71%] tests/unit/matchers/url_test.py ............................ [ 84%] tests/unit/mock_engine_test.py ....x [ 86%] tests/unit/mock_test.py .FxxF......................... [ 99%] tests/unit/regex_test.py .. [100%] =================================== FAILURES =================================== _______________________ test_examples[aiohttp_client.py] _______________________ example = 'aiohttp_client.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.12', 'examples/aiohttp_client.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stderr call ----------------------------- /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/aiohttp_client.py:30: DeprecationWarning: There is no current event loop loop = asyncio.get_event_loop() Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/aiohttp_client.py", line 31, in loop.run_until_complete(main(loop)) File "/usr/lib/python3.12/asyncio/base_events.py", line 686, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/aiohttp_client.py", line 28, in main await fetch(session, "http://httpbin.org/ip", bytearray("foo bar", "utf-8")) File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/aiohttp_client.py", line 10, in fetch with async_timeout.timeout(10): ^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: 'Timeout' object does not support the context manager protocol _________________________ test_examples[decorators.py] _________________________ example = 'decorators.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.12', 'examples/decorators.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- #1 status: 200 #2 status: 204 Is done: True Pending mocks: [] ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/socket.py", line 976, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() File "/usr/lib/python3.12/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib/python3.12/http/client.py", line 1091, in _send_output self.send(msg) File "/usr/lib/python3.12/http/client.py", line 1035, in send self.connect() File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 667, in send resp = conn.urlopen( ^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( ^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/400 (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/decorators.py", line 26, in res = requests.get("http://httpbin.org/status/400") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/adapters.py", line 700, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/400 (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) ________________________ test_examples[network_mode.py] ________________________ example = 'network_mode.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.12', 'examples/network_mode.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- Mock status: 201 ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/socket.py", line 976, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() File "/usr/lib/python3.12/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib/python3.12/http/client.py", line 1091, in _send_output self.send(msg) File "/usr/lib/python3.12/http/client.py", line 1035, in send self.connect() File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 667, in send resp = conn.urlopen( ^^^^^^^^^^^^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/pook/interceptors/urllib3.py", line 175, in handler return self._on_request( ^^^^^^^^^^^^^^^^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/pook/interceptors/urllib3.py", line 137, in _on_request return urlopen(pool, method, url, body=body, headers=headers, **kw) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/pook/interceptors/urllib3.py", line 175, in handler return self._on_request( ^^^^^^^^^^^^^^^^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/pook/interceptors/urllib3.py", line 137, in _on_request return urlopen(pool, method, url, body=body, headers=headers, **kw) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( ^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/network_mode.py", line 22, in res = requests.get("http://httpbin.org/ip") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/adapters.py", line 700, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) _______________________ test_examples[urllib3_client.py] _______________________ example = 'urllib3_client.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.12', 'examples/urllib3_client.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- #1 status: 204 ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/socket.py", line 976, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() File "/usr/lib/python3.12/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib/python3.12/http/client.py", line 1091, in _send_output self.send(msg) File "/usr/lib/python3.12/http/client.py", line 1035, in send self.connect() File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/urllib3_client.py", line 17, in r = http.request("GET", "http://httpbin.org/status/404") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/_request_methods.py", line 135, in request return self.request_encode_url( ^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/_request_methods.py", line 182, in request_encode_url return self.urlopen(method, url, **extra_kw) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 443, in urlopen response = conn.urlopen(method, u.request_uri, **kw) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 873, in urlopen return self.urlopen( ^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 873, in urlopen return self.urlopen( ^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 873, in urlopen return self.urlopen( ^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( ^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/404 (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) _____________________ test_examples[network_mode_httpx.py] _____________________ example = 'network_mode_httpx.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.12', 'examples/network_mode_httpx.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- Mock status: 201 ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 72, in map_httpcore_exceptions yield File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 236, in handle_request resp = self._pool.handle_request(req) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py", line 256, in handle_request raise exc from None File "/usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py", line 236, in handle_request response = connection.handle_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpcore/_sync/connection.py", line 101, in handle_request raise exc File "/usr/lib/python3/dist-packages/httpcore/_sync/connection.py", line 78, in handle_request stream = self._connect(request) ^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpcore/_sync/connection.py", line 124, in _connect stream = self._network_backend.connect_tcp(**kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpcore/_backends/sync.py", line 207, in connect_tcp with map_exceptions(exc_map): ^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/usr/lib/python3/dist-packages/httpcore/_exceptions.py", line 14, in map_exceptions raise to_exc(exc) from exc httpcore.ConnectError: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/network_mode_httpx.py", line 22, in res = httpx.get("http://httpbin.org/ip") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_api.py", line 210, in get return request( ^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_api.py", line 118, in request return client.request( ^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 837, in request return self.send(request, auth=auth, follow_redirects=follow_redirects) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 926, in send response = self._send_handling_auth( ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 954, in _send_handling_auth response = self._send_handling_redirects( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 991, in _send_handling_redirects response = self._send_single_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 1027, in _send_single_request response = transport.handle_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/pook/interceptors/_httpx.py", line 141, in handle_request return transport.handle_request(request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 235, in handle_request with map_httpcore_exceptions(): ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/contextlib.py", line 158, in __exit__ self.gen.throw(value) File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 89, in map_httpcore_exceptions raise mapped_exc(message) from exc httpx.ConnectError: [Errno -3] Temporary failure in name resolution ____________________ test_examples[mock_context_manager.py] ____________________ example = 'mock_context_manager.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.12', 'examples/mock_context_manager.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- #1 Status: 403 #1 Headers: {'pepe': 'lopez', 'Content-Type': 'application/json'} #1 Body: {'error': 'not found'} ---------------- #2 Status: 403 #2 Headers: {'pepe': 'lopez', 'Content-Type': 'application/json'} #2 Body: {'error': 'not found'} ---------------- Mock is done: True Mock matches: 2 Is done: True Pending mocks: [] Unmatched requests: [] ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/socket.py", line 976, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( ^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() File "/usr/lib/python3.12/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/lib/python3.12/http/client.py", line 1091, in _send_output self.send(msg) File "/usr/lib/python3.12/http/client.py", line 1035, in send self.connect() File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 667, in send resp = conn.urlopen( ^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( ^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/examples/mock_context_manager.py", line 37, in res = requests.get("http://httpbin.org/ip") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/adapters.py", line 700, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) ______________________________ test_requests_get _______________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'foo.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: def test_requests_get(): body = {"error": "not found"} pook.get("http://foo.com").reply(404).json(body) > res = requests.get("http://foo.com") tests/integration/pook_requests_test.py:13: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/requests/api.py:73: in get return request("get", url, params=params, **kwargs) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError ___________________________ test_requests_match_url ____________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'foo.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: def test_requests_match_url(): body = {"foo": "bar"} pook.get("http://foo.com").reply(200).json(body) > res = requests.get("http://foo.com") tests/integration/pook_requests_test.py:23: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/requests/api.py:73: in get return request("get", url, params=params, **kwargs) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError _______________________ test_requests_match_query_params _______________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'foo.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/?foo=bar', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query='foo=bar', fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/?foo=bar', response = None error = NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: /?foo=bar (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: def test_requests_match_query_params(): body = {"foo": "bar"} (pook.get("http://foo.com").params({"foo": "bar"}).reply(200).json(body)) > res = requests.get("http://foo.com", params={"foo": "bar"}) tests/integration/pook_requests_test.py:33: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/requests/api.py:73: in get return request("get", url, params=params, **kwargs) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: /?foo=bar (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError _________________ TestStandardAiohttp.test_activate_deactivate _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardAiohttp.test_network_mode _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' url_500 = 'http://127.0.0.1:36845/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardAiohttp.test_network_mode_hostname ________________ self = req = traces = [] timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=30, ceil_threshold=5) async def _create_direct_connection( self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout", *, client_error: Type[Exception] = ClientConnectorError, ) -> Tuple[asyncio.Transport, ResponseHandler]: sslcontext = self._get_ssl_context(req) fingerprint = self._get_fingerprint(req) host = req.url.raw_host assert host is not None # Replace multiple trailing dots with a single one. # A trailing dot is only present for fully-qualified domain names. # See https://github.com/aio-libs/aiohttp/pull/7364. if host.endswith(".."): host = host.rstrip(".") + "." port = req.port assert port is not None try: # Cancelling this lookup should not cancel the underlying lookup # or else the cancel event will get broadcast to all the waiters # across all connections. > hosts = await self._resolve_host(host, port, traces=traces) /usr/lib/python3/dist-packages/aiohttp/connector.py:1335: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/aiohttp/connector.py:989: in _resolve_host return await asyncio.shield(resolved_host_task) /usr/lib/python3/dist-packages/aiohttp/connector.py:1020: in _resolve_host_with_throttle addrs = await self._resolver.resolve(host, port, family=self._family) /usr/lib/python3/dist-packages/aiohttp/resolver.py:38: in resolve infos = await self._loop.getaddrinfo( /usr/lib/python3.12/asyncio/base_events.py:900: in getaddrinfo return await self.run_in_executor( /usr/lib/python3.12/concurrent/futures/thread.py:59: in run result = self.fn(*self.args, **self.kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = type = , proto = 0 flags = def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/base.py:35: in make_request return self.loop.run_until_complete( /usr/lib/python3.12/asyncio/base_events.py:686: in run_until_complete return future.result() tests/unit/interceptors/aiohttp_test.py:16: in amake_request response = await session.request( /usr/lib/python3/dist-packages/aiohttp/client.py:663: in _request conn = await self._connector.connect( /usr/lib/python3/dist-packages/aiohttp/connector.py:538: in connect proto = await self._create_connection(req, traces, timeout) /usr/lib/python3/dist-packages/aiohttp/connector.py:1050: in _create_connection _, proto = await self._create_direct_connection(req, traces, timeout) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = traces = [] timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=30, ceil_threshold=5) async def _create_direct_connection( self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout", *, client_error: Type[Exception] = ClientConnectorError, ) -> Tuple[asyncio.Transport, ResponseHandler]: sslcontext = self._get_ssl_context(req) fingerprint = self._get_fingerprint(req) host = req.url.raw_host assert host is not None # Replace multiple trailing dots with a single one. # A trailing dot is only present for fully-qualified domain names. # See https://github.com/aio-libs/aiohttp/pull/7364. if host.endswith(".."): host = host.rstrip(".") + "." port = req.port assert port is not None try: # Cancelling this lookup should not cancel the underlying lookup # or else the cancel event will get broadcast to all the waiters # across all connections. hosts = await self._resolve_host(host, port, traces=traces) except OSError as exc: if exc.errno is None and isinstance(exc, asyncio.TimeoutError): raise # in case of proxy it is not ClientProxyConnectionError # it is problem of resolving proxy ip itself > raise ClientConnectorDNSError(req.connection_key, exc) from exc E aiohttp.client_exceptions.ClientConnectorDNSError: Cannot connect to host example.com:80 ssl:default [Temporary failure in name resolution] /usr/lib/python3/dist-packages/aiohttp/connector.py:1341: ClientConnectorDNSError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 ______________ TestStandardAiohttp.test_multiple_network_filters _______________ self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 ____________________ TestStandardAiohttp.test_json_request _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardAiohttp.test_json_response ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardAiohttp.test_json_request_and_response ______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _____________________ TestStandardAiohttp.test_header_sent _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardAiohttp.test_mocked_response_headers _______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _________________ TestStandardAiohttp.test_mutli_value_headers _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardAiohttp.test_mutli_value_response_headers _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardAiohttp.test_unmatched_headers_none_sent _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardAsyncHttpx.test_activate_deactivate ________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardAsyncHttpx.test_network_mode ___________________ self = url_404 = 'http://127.0.0.1:36845/status/404' url_500 = 'http://127.0.0.1:36845/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardAsyncHttpx.test_network_mode_hostname _______________ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: > yield /usr/lib/python3/dist-packages/httpx/_transports/default.py:72: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/httpx/_transports/default.py:377: in handle_async_request resp = await self._pool.handle_async_request(req) /usr/lib/python3/dist-packages/httpcore/_async/connection_pool.py:256: in handle_async_request raise exc from None /usr/lib/python3/dist-packages/httpcore/_async/connection_pool.py:236: in handle_async_request response = await connection.handle_async_request( /usr/lib/python3/dist-packages/httpcore/_async/connection.py:101: in handle_async_request raise exc /usr/lib/python3/dist-packages/httpcore/_async/connection.py:78: in handle_async_request stream = await self._connect(request) /usr/lib/python3/dist-packages/httpcore/_async/connection.py:124: in _connect stream = await self._network_backend.connect_tcp(**kwargs) /usr/lib/python3/dist-packages/httpcore/_backends/auto.py:31: in connect_tcp return await self._backend.connect_tcp( /usr/lib/python3/dist-packages/httpcore/_backends/anyio.py:113: in connect_tcp with map_exceptions(exc_map): /usr/lib/python3.12/contextlib.py:158: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ map = {: , : , : } @contextlib.contextmanager def map_exceptions(map: ExceptionMapping) -> typing.Iterator[None]: try: yield except Exception as exc: # noqa: PIE786 for from_exc, to_exc in map.items(): if isinstance(exc, from_exc): > raise to_exc(exc) from exc E httpcore.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpcore/_exceptions.py:14: ConnectError The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/base.py:35: in make_request return self.loop.run_until_complete( /usr/lib/python3.12/asyncio/base_events.py:686: in run_until_complete return future.result() tests/unit/interceptors/httpx_test.py:17: in amake_request response = await client.request( /usr/lib/python3/dist-packages/httpx/_client.py:1585: in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) /usr/lib/python3/dist-packages/httpx/_client.py:1674: in send response = await self._send_handling_auth( /usr/lib/python3/dist-packages/httpx/_client.py:1702: in _send_handling_auth response = await self._send_handling_redirects( /usr/lib/python3/dist-packages/httpx/_client.py:1739: in _send_handling_redirects response = await self._send_single_request(request) /usr/lib/python3/dist-packages/httpx/_client.py:1776: in _send_single_request response = await transport.handle_async_request(request) /usr/lib/python3/dist-packages/httpx/_transports/default.py:376: in handle_async_request with map_httpcore_exceptions(): /usr/lib/python3.12/contextlib.py:158: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: yield except Exception as exc: mapped_exc = None for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): if not isinstance(exc, from_exc): continue # We want to map to the most specific exception we can find. # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to # `httpx.ReadTimeout`, not just `httpx.TimeoutException`. if mapped_exc is None or issubclass(to_exc, mapped_exc): mapped_exc = to_exc if mapped_exc is None: # pragma: no cover raise message = str(exc) > raise mapped_exc(message) from exc E httpx.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpx/_transports/default.py:89: ConnectError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 _____________ TestStandardAsyncHttpx.test_multiple_network_filters _____________ self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/401 HTTP/1.1" 401 0 ___________________ TestStandardAsyncHttpx.test_json_request ___________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 __________________ TestStandardAsyncHttpx.test_json_response ___________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardAsyncHttpx.test_json_request_and_response _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardAsyncHttpx.test_header_sent ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardAsyncHttpx.test_mocked_response_headers ______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardAsyncHttpx.test_mutli_value_headers ________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ___________ TestStandardAsyncHttpx.test_mutli_value_response_headers ___________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ___________ TestStandardAsyncHttpx.test_unmatched_headers_none_sent ____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardSyncHttpx.test_activate_deactivate ________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardSyncHttpx.test_network_mode ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' url_500 = 'http://127.0.0.1:36845/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:25] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardSyncHttpx.test_network_mode_hostname _______________ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: > yield /usr/lib/python3/dist-packages/httpx/_transports/default.py:72: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/httpx/_transports/default.py:236: in handle_request resp = self._pool.handle_request(req) /usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py:256: in handle_request raise exc from None /usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py:236: in handle_request response = connection.handle_request( /usr/lib/python3/dist-packages/httpcore/_sync/connection.py:101: in handle_request raise exc /usr/lib/python3/dist-packages/httpcore/_sync/connection.py:78: in handle_request stream = self._connect(request) /usr/lib/python3/dist-packages/httpcore/_sync/connection.py:124: in _connect stream = self._network_backend.connect_tcp(**kwargs) /usr/lib/python3/dist-packages/httpcore/_backends/sync.py:207: in connect_tcp with map_exceptions(exc_map): /usr/lib/python3.12/contextlib.py:158: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ map = {: , : } @contextlib.contextmanager def map_exceptions(map: ExceptionMapping) -> typing.Iterator[None]: try: yield except Exception as exc: # noqa: PIE786 for from_exc, to_exc in map.items(): if isinstance(exc, from_exc): > raise to_exc(exc) from exc E httpcore.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpcore/_exceptions.py:14: ConnectError The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/httpx_test.py:26: in make_request response = httpx.request( /usr/lib/python3/dist-packages/httpx/_api.py:118: in request return client.request( /usr/lib/python3/dist-packages/httpx/_client.py:837: in request return self.send(request, auth=auth, follow_redirects=follow_redirects) /usr/lib/python3/dist-packages/httpx/_client.py:926: in send response = self._send_handling_auth( /usr/lib/python3/dist-packages/httpx/_client.py:954: in _send_handling_auth response = self._send_handling_redirects( /usr/lib/python3/dist-packages/httpx/_client.py:991: in _send_handling_redirects response = self._send_single_request(request) /usr/lib/python3/dist-packages/httpx/_client.py:1027: in _send_single_request response = transport.handle_request(request) /usr/lib/python3/dist-packages/httpx/_transports/default.py:235: in handle_request with map_httpcore_exceptions(): /usr/lib/python3.12/contextlib.py:158: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: yield except Exception as exc: mapped_exc = None for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): if not isinstance(exc, from_exc): continue # We want to map to the most specific exception we can find. # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to # `httpx.ReadTimeout`, not just `httpx.TimeoutException`. if mapped_exc is None or issubclass(to_exc, mapped_exc): mapped_exc = to_exc if mapped_exc is None: # pragma: no cover raise message = str(exc) > raise mapped_exc(message) from exc E httpx.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpx/_transports/default.py:89: ConnectError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 _____________ TestStandardSyncHttpx.test_multiple_network_filters ______________ self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 ___________________ TestStandardSyncHttpx.test_json_request ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardSyncHttpx.test_json_response ___________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardSyncHttpx.test_json_request_and_response _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardSyncHttpx.test_header_sent ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardSyncHttpx.test_mocked_response_headers ______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardSyncHttpx.test_mutli_value_headers ________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ___________ TestStandardSyncHttpx.test_mutli_value_response_headers ____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardSyncHttpx.test_unmatched_headers_none_sent ____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 __________________________________ test_sync ___________________________________ URL = 'http://127.0.0.1:36845/status/404' def test_sync(URL): pook.get(URL).times(1).reply(200).body("123") response = httpx.get(URL) > assert response.status_code == 200 E assert 404 == 200 E + where 404 = .status_code tests/unit/interceptors/httpx_test.py:43: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 __________________________________ test_json ___________________________________ URL = 'http://127.0.0.1:36845/status/404' def test_json(URL): ( pook.post(URL) .times(1) .json({"id": "123abc"}) .reply(200) .json({"title": "123abc title"}) ) response = httpx.post(URL, json={"id": "123abc"}) > assert response.status_code == 200 E assert 404 == 200 E + where 404 = .status_code tests/unit/interceptors/httpx_test.py:67: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "POST /status/404 HTTP/1.1" 404 0 __________________________ test_streaming[iter_bytes] __________________________ URL = 'http://127.0.0.1:36845/status/404', response_method = 'iter_bytes' @pytest.mark.parametrize("response_method", ("iter_bytes", "iter_raw")) def test_streaming(URL, response_method): streamed_response = b"streamed response" pook.get(URL).times(1).reply(200).body(streamed_response).mock with httpx.stream("GET", URL) as r: read_bytes = list(getattr(r, response_method)(chunk_size=1)) > assert len(read_bytes) == len(streamed_response) E AssertionError: assert 0 == 17 E + where 0 = len([]) E + and 17 = len(b'streamed response') tests/unit/interceptors/httpx_test.py:79: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ___________________________ test_streaming[iter_raw] ___________________________ URL = 'http://127.0.0.1:36845/status/404', response_method = 'iter_raw' @pytest.mark.parametrize("response_method", ("iter_bytes", "iter_raw")) def test_streaming(URL, response_method): streamed_response = b"streamed response" pook.get(URL).times(1).reply(200).body(streamed_response).mock with httpx.stream("GET", URL) as r: read_bytes = list(getattr(r, response_method)(chunk_size=1)) > assert len(read_bytes) == len(streamed_response) E AssertionError: assert 0 == 17 E + where 0 = len([]) E + and 17 = len(b'streamed response') tests/unit/interceptors/httpx_test.py:79: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ___________________________ test_redirect_following ____________________________ URL = 'http://127.0.0.1:36845/status/404' def test_redirect_following(URL): urls = [URL, f"{URL}/redirected", f"{URL}/redirected_again"] for req, dest in zip_longest(urls, urls[1:], fillvalue=None): if not dest: pook.get(req).times(1).reply(200).body("found at last") else: pook.get(req).times(1).reply(302).header("Location", dest) response = httpx.get(URL, follow_redirects=True) > assert response.status_code == 200 E assert 404 == 200 E + where 404 = .status_code tests/unit/interceptors/httpx_test.py:93: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _________________ TestStandardUrllib3.test_activate_deactivate _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardUrllib3.test_network_mode _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' url_500 = 'http://127.0.0.1:36845/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardUrllib3.test_network_mode_hostname ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None, headers = {} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False, timeout = <_TYPE_DEFAULT.token: -1> pool_timeout = None, release_conn = True, chunked = False, body_pos = None preload_content = True, decode_content = True, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/urllib3_test.py:21: in make_request response = http.request(method, url, content, headers=req_headers) /usr/lib/python3/dist-packages/urllib3/_request_methods.py:135: in request return self.request_encode_url( /usr/lib/python3/dist-packages/urllib3/_request_methods.py:182: in request_encode_url return self.urlopen(method, url, **extra_kw) /usr/lib/python3/dist-packages/urllib3/poolmanager.py:443: in urlopen response = conn.urlopen(method, u.request_uri, **kw) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:873: in urlopen return self.urlopen( /usr/lib/python3/dist-packages/urllib3/connectionpool.py:873: in urlopen return self.urlopen( /usr/lib/python3/dist-packages/urllib3/connectionpool.py:873: in urlopen return self.urlopen( /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='example.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:870 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")': / WARNING urllib3.connectionpool:connectionpool.py:870 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")': / WARNING urllib3.connectionpool:connectionpool.py:870 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")': / ______________ TestStandardUrllib3.test_multiple_network_filters _______________ self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 ____________________ TestStandardUrllib3.test_json_request _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardUrllib3.test_json_response ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardUrllib3.test_json_request_and_response ______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _____________________ TestStandardUrllib3.test_header_sent _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardUrllib3.test_mocked_response_headers _______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _________________ TestStandardUrllib3.test_mutli_value_headers _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardUrllib3.test_mutli_value_response_headers _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardUrllib3.test_unmatched_headers_none_sent _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardRequests.test_activate_deactivate _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardRequests.test_network_mode ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' url_500 = 'http://127.0.0.1:36845/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardRequests.test_network_mode_hostname ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='example.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/urllib3_test.py:35: in make_request response = requests.request(method, url, data=content, headers=req_headers) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='example.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:26] "GET /status/401 HTTP/1.1" 401 0 ______________ TestStandardRequests.test_multiple_network_filters ______________ self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 ____________________ TestStandardRequests.test_json_request ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardRequests.test_json_response ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardRequests.test_json_request_and_response ______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardRequests.test_header_sent _____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardRequests.test_mocked_response_headers _______________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardRequests.test_mutli_value_headers _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardRequests.test_mutli_value_response_headers ____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardRequests.test_unmatched_headers_none_sent _____________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ____________________________ test_post_with_headers ____________________________ URL = 'http://127.0.0.1:36845/foo' @pytest.mark.pook def test_post_with_headers(URL): mock = pook.post(URL).header("k", "v").reply(200).mock http = urllib3.PoolManager(headers={"k": "v"}) resp = http.request("POST", URL) > assert resp.status == 200 E assert 404 == 200 E + where 404 = .status tests/unit/interceptors/urllib3_test.py:112: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "POST /foo HTTP/1.1" 404 207 _____________________ TestUrllib.test_activate_deactivate ______________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _________________________ TestUrllib.test_network_mode _________________________ self = url_404 = 'http://127.0.0.1:36845/status/404' url_500 = 'http://127.0.0.1:36845/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestUrllib.test_network_mode_hostname _____________________ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: > h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.12/urllib/request.py:1344: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/http/client.py:1336: in request self._send_request(method, url, body, headers, encode_chunked) /usr/lib/python3.12/http/client.py:1382: in _send_request self.endheaders(body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3.12/http/client.py:1001: in connect self.sock = self._create_connection( /usr/lib/python3.12/socket.py:841: in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = 0, type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror During handling of the above exception, another exception occurred: self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/urllib_test.py:28: in make_request response: HTTPResponse = urlopen(request) /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:515: in open response = self._open(req, data) /usr/lib/python3.12/urllib/request.py:532: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) /usr/lib/python3.12/urllib/request.py:1373: in http_open return self.do_open(http.client.HTTPConnection, req) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error > raise URLError(err) E urllib.error.URLError: /usr/lib/python3.12/urllib/request.py:1347: URLError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 ___________________ TestUrllib.test_multiple_network_filters ___________________ self = url_401 = 'http://127.0.0.1:36845/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/401 HTTP/1.1" 401 0 _________________________ TestUrllib.test_json_request _________________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ________________________ TestUrllib.test_json_response _________________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 __________________ TestUrllib.test_json_request_and_response ___________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _________________________ TestUrllib.test_header_sent __________________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) > status, body, _ = self.make_request("GET", url_404, headers=headers) E ValueError: not enough values to unpack (expected 3, got 2) tests/unit/interceptors/base.py:205: ValueError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestUrllib.test_mocked_response_headers ____________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") > status, _, headers = self.make_request("GET", url_404) E ValueError: not enough values to unpack (expected 3, got 2) tests/unit/interceptors/base.py:215: ValueError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _____________________ TestUrllib.test_mutli_value_headers ______________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _________________ TestUrllib.test_mutli_value_response_headers _________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) > status, _, headers = self.make_request("GET", url_404) E ValueError: not enough values to unpack (expected 3, got 2) tests/unit/interceptors/base.py:237: ValueError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _________________ TestUrllib.test_unmatched_headers_none_sent __________________ self = url_404 = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:27] "GET /status/404 HTTP/1.1" 404 0 _______________________________ test_urllib_ssl ________________________________ self = http_class = req = http_conn_args = {'context': } host = '127.0.0.1:9', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: > h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.12/urllib/request.py:1344: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/http/client.py:1336: in request self._send_request(method, url, body, headers, encode_chunked) /usr/lib/python3.12/http/client.py:1382: in _send_request self.endheaders(body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3.12/http/client.py:1470: in connect super().connect() /usr/lib/python3.12/http/client.py:1001: in connect self.sock = self._create_connection( /usr/lib/python3.12/socket.py:865: in create_connection raise exceptions[0] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ address = ('127.0.0.1', 9), timeout = source_address = None def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None, *, all_errors=False): """Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, port)``) and return the socket object. Passing the optional *timeout* parameter will set the timeout on the socket instance before attempting to connect. If no *timeout* is supplied, the global default timeout setting returned by :func:`getdefaulttimeout` is used. If *source_address* is set it must be a tuple of (host, port) for the socket to bind as a source address before making the connection. A host of '' or port 0 tells the OS to use the default. When a connection cannot be created, raises the last error if *all_errors* is False, and an ExceptionGroup of all errors if *all_errors* is True. """ host, port = address exceptions = [] for res in getaddrinfo(host, port, 0, SOCK_STREAM): af, socktype, proto, canonname, sa = res sock = None try: sock = socket(af, socktype, proto) if timeout is not _GLOBAL_DEFAULT_TIMEOUT: sock.settimeout(timeout) if source_address: sock.bind(source_address) > sock.connect(sa) E ConnectionRefusedError: [Errno 111] Connection refused /usr/lib/python3.12/socket.py:850: ConnectionRefusedError During handling of the above exception, another exception occurred: @pytest.mark.pook def test_urllib_ssl(): pook.get("https://example.com").reply(200).body("Hello from pook") > res = urlopen("https://example.com") tests/unit/interceptors/urllib_test.py:37: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:515: in open response = self._open(req, data) /usr/lib/python3.12/urllib/request.py:532: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) /usr/lib/python3.12/urllib/request.py:1392: in https_open return self.do_open(http.client.HTTPSConnection, req, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = http_conn_args = {'context': } host = '127.0.0.1:9', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error > raise URLError(err) E urllib.error.URLError: /usr/lib/python3.12/urllib/request.py:1347: URLError ______________________________ test_urllib_clear _______________________________ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: > h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.12/urllib/request.py:1344: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/http/client.py:1336: in request self._send_request(method, url, body, headers, encode_chunked) /usr/lib/python3.12/http/client.py:1382: in _send_request self.endheaders(body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.12/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.12/http/client.py:1035: in send self.connect() /usr/lib/python3.12/http/client.py:1001: in connect self.sock = self._create_connection( /usr/lib/python3.12/socket.py:841: in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = 0, type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.12/socket.py:976: gaierror During handling of the above exception, another exception occurred: @pytest.mark.pook def test_urllib_clear(): pook.get("http://example.com").reply(200).body("Hello from pook") > res = urlopen("http://example.com") tests/unit/interceptors/urllib_test.py:45: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:515: in open response = self._open(req, data) /usr/lib/python3.12/urllib/request.py:532: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) /usr/lib/python3.12/urllib/request.py:1373: in http_open return self.do_open(http.client.HTTPConnection, req) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.12'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error > raise URLError(err) E urllib.error.URLError: /usr/lib/python3.12/urllib/request.py:1347: URLError ______ test_headers_not_matching[Missing request header str expectation] _______ expected = {'Content-Type': 'application/pdf'}, requested = {} explanation = ["HeadersMatcher: Header 'Content-Type' not present"] @pytest.mark.parametrize( ("expected", "requested", "explanation"), ( pytest.param( {"Content-Type": "application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header str expectation", ), pytest.param( {"Content-Type": b"application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header bytes expectation", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, matching types", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, str expectation byte actual", ), pytest.param( {"Content-Type": b"application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, bytes expectation str actual", ), pytest.param( {"Content-Type": "re/json/"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: Regex didn't match: 'json' not found in " "'application/xml'" ) ], id="Non-matching values, re-format str expectation", ), ), ) def test_headers_not_matching(expected, requested, explanation): mock = pook.get("https://example.com") if expected: mock.headers(expected) request = pook.Request() request.url = "https://example.com" if requested: request.headers = requested matched, actual_explanation = mock.match(request) assert not matched > assert explanation == actual_explanation E assert ["HeadersMatc... not present"] == ['HeadersMatc...====.headers'] E E At index 0 diff: "HeadersMatcher: Header 'Content-Type' not present" != "HeadersMatcher: Header 'Content-Type' not present\nassert 'Content-Type' in HTTPHeaderDict({})\n + where HTTPHeaderDict({}) = ==================================================\\nMethod: GET\\nURL: https://example.com\\n==================================================.headers" E Use -v to get more diff tests/unit/matchers/headers_test.py:171: AssertionError _____ test_headers_not_matching[Missing request header bytes expectation] ______ expected = {'Content-Type': b'application/pdf'}, requested = {} explanation = ["HeadersMatcher: Header 'Content-Type' not present"] @pytest.mark.parametrize( ("expected", "requested", "explanation"), ( pytest.param( {"Content-Type": "application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header str expectation", ), pytest.param( {"Content-Type": b"application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header bytes expectation", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, matching types", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, str expectation byte actual", ), pytest.param( {"Content-Type": b"application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, bytes expectation str actual", ), pytest.param( {"Content-Type": "re/json/"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: Regex didn't match: 'json' not found in " "'application/xml'" ) ], id="Non-matching values, re-format str expectation", ), ), ) def test_headers_not_matching(expected, requested, explanation): mock = pook.get("https://example.com") if expected: mock.headers(expected) request = pook.Request() request.url = "https://example.com" if requested: request.headers = requested matched, actual_explanation = mock.match(request) assert not matched > assert explanation == actual_explanation E assert ["HeadersMatc... not present"] == ['HeadersMatc...====.headers'] E E At index 0 diff: "HeadersMatcher: Header 'Content-Type' not present" != "HeadersMatcher: Header 'Content-Type' not present\nassert 'Content-Type' in HTTPHeaderDict({})\n + where HTTPHeaderDict({}) = ==================================================\\nMethod: GET\\nURL: https://example.com\\n==================================================.headers" E Use -v to get more diff tests/unit/matchers/headers_test.py:171: AssertionError ______________________ test_param_exists_empty_disallowed ______________________ URL = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_param_exists_empty_disallowed(URL): pook.get(URL).param_exists("x").reply(200) with pytest.raises(PookNoMatches): > urlopen(f"{URL}?x") tests/unit/matchers/query_test.py:19: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:521: in open response = meth(req, response) /usr/lib/python3.12/urllib/request.py:630: in http_response response = self.parent.error( /usr/lib/python3.12/urllib/request.py:559: in error return self._call_chain(*args) /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = fp = , code = 404 msg = 'NOT FOUND', hdrs = def http_error_default(self, req, fp, code, msg, hdrs): > raise HTTPError(req.full_url, code, msg, hdrs, fp) E urllib.error.HTTPError: HTTP Error 404: NOT FOUND /usr/lib/python3.12/urllib/request.py:639: HTTPError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:28] "GET /status/404?x HTTP/1.1" 404 0 _______________________ test_param_exists_empty_allowed ________________________ URL = 'http://127.0.0.1:36845/status/404' @pytest.mark.pook def test_param_exists_empty_allowed(URL): pook.get(URL).param_exists("x", allow_empty=True).reply(200) > res = urlopen(f"{URL}?x") tests/unit/matchers/query_test.py:26: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:521: in open response = meth(req, response) /usr/lib/python3.12/urllib/request.py:630: in http_response response = self.parent.error( /usr/lib/python3.12/urllib/request.py:559: in error return self._call_chain(*args) /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = fp = , code = 404 msg = 'NOT FOUND', hdrs = def http_error_default(self, req, fp, code, msg, hdrs): > raise HTTPError(req.full_url, code, msg, hdrs, fp) E urllib.error.HTTPError: HTTP Error 404: NOT FOUND /usr/lib/python3.12/urllib/request.py:639: HTTPError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:28] "GET /status/404?x HTTP/1.1" 404 0 ________________________ test_mock_constructor[params] _________________________ param_kwargs = {'params': {'x': '1'}}, query_string = '?x=1' @pytest.mark.parametrize( ("param_kwargs", "query_string"), ( pytest.param({"params": {"x": "1"}}, "?x=1", id="params"), pytest.param( {"param": ("y", "pook")}, "?y=pook", marks=pytest.mark.xfail( condition=True, reason="Constructor does not correctly handle multi-argument methods from kwargs", ), id="param", ), pytest.param( {"param_exists": "z"}, "?z", marks=pytest.mark.xfail( condition=True, reason="Constructor does not have a method for passing `allow_empty` to `param_exists`", ), id="param_exists_empty_on_request", ), pytest.param( {"param_exists": "z"}, "?z=123", id="param_exists_has_value", ), ), ) def test_mock_constructor(param_kwargs, query_string): # Should not raise mock = Mock( url="https://httpbin.org/404", reply_status=200, response_json={"hello": "from pook"}, **param_kwargs, ) with pook.use(): pook.engine().add_mock(mock) > res = urlopen(f"https://httpbin.org/404{query_string}") tests/unit/mock_test.py:70: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:515: in open response = self._open(req, data) /usr/lib/python3.12/urllib/request.py:532: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) /usr/lib/python3.12/urllib/request.py:1392: in https_open return self.do_open(http.client.HTTPSConnection, req, /usr/lib/python3.12/urllib/request.py:1344: in do_open h.request(req.get_method(), req.selector, req.data, headers, pook/interceptors/http.py:110: in handler return self._on_request( pook/interceptors/http.py:61: in _on_request mock = self.engine.match(req) pook/engine.py:448: in match self.no_matches(msg) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = msg = "pook error!\n\n=> Cannot match any mock for the following request:\n=================================================...============\n\n=> Detailed matching errors:\nURLMatcher: 'httpbin.org' != '127.0.0.1'\n- httpbin.org\n+ 127.0.0.1\n\n" def no_matches(self, msg): """Raise `PookNoMatches` and reduce pytest printed stacktrace noise""" > raise PookNoMatches(msg) E pook.exceptions.PookNoMatches: pook error! E E => Cannot match any mock for the following request: E ================================================== E Method: GET E URL: https://127.0.0.1:9/404?x=1 E Query: {'x': ['1']} E Headers: HTTPHeaderDict({'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.12', 'Connection': 'close'}) E ================================================== E E => Detailed matching errors: E URLMatcher: 'httpbin.org' != '127.0.0.1' E - httpbin.org E + 127.0.0.1 pook/engine.py:455: PookNoMatches ________________ test_mock_constructor[param_exists_has_value] _________________ param_kwargs = {'param_exists': 'z'}, query_string = '?z=123' @pytest.mark.parametrize( ("param_kwargs", "query_string"), ( pytest.param({"params": {"x": "1"}}, "?x=1", id="params"), pytest.param( {"param": ("y", "pook")}, "?y=pook", marks=pytest.mark.xfail( condition=True, reason="Constructor does not correctly handle multi-argument methods from kwargs", ), id="param", ), pytest.param( {"param_exists": "z"}, "?z", marks=pytest.mark.xfail( condition=True, reason="Constructor does not have a method for passing `allow_empty` to `param_exists`", ), id="param_exists_empty_on_request", ), pytest.param( {"param_exists": "z"}, "?z=123", id="param_exists_has_value", ), ), ) def test_mock_constructor(param_kwargs, query_string): # Should not raise mock = Mock( url="https://httpbin.org/404", reply_status=200, response_json={"hello": "from pook"}, **param_kwargs, ) with pook.use(): pook.engine().add_mock(mock) > res = urlopen(f"https://httpbin.org/404{query_string}") tests/unit/mock_test.py:70: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.12/urllib/request.py:215: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.12/urllib/request.py:515: in open response = self._open(req, data) /usr/lib/python3.12/urllib/request.py:532: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.12/urllib/request.py:492: in _call_chain result = func(*args) /usr/lib/python3.12/urllib/request.py:1392: in https_open return self.do_open(http.client.HTTPSConnection, req, /usr/lib/python3.12/urllib/request.py:1344: in do_open h.request(req.get_method(), req.selector, req.data, headers, pook/interceptors/http.py:110: in handler return self._on_request( pook/interceptors/http.py:61: in _on_request mock = self.engine.match(req) pook/engine.py:448: in match self.no_matches(msg) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = msg = "pook error!\n\n=> Cannot match any mock for the following request:\n=================================================...============\n\n=> Detailed matching errors:\nURLMatcher: 'httpbin.org' != '127.0.0.1'\n- httpbin.org\n+ 127.0.0.1\n\n" def no_matches(self, msg): """Raise `PookNoMatches` and reduce pytest printed stacktrace noise""" > raise PookNoMatches(msg) E pook.exceptions.PookNoMatches: pook error! E E => Cannot match any mock for the following request: E ================================================== E Method: GET E URL: https://127.0.0.1:9/404?z=123 E Query: {'z': ['123']} E Headers: HTTPHeaderDict({'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.12', 'Connection': 'close'}) E ================================================== E E => Detailed matching errors: E URLMatcher: 'httpbin.org' != '127.0.0.1' E - httpbin.org E + 127.0.0.1 pook/engine.py:455: PookNoMatches =============================== warnings summary =============================== ../../../../../../usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441 /usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441: PytestConfigWarning: Unknown config option: asyncio_default_fixture_loop_scope self._warn_or_fail_if_strict(f"Unknown config option: {key}\n") ../../../../../../usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441 /usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441: PytestConfigWarning: Unknown config option: asyncio_mode self._warn_or_fail_if_strict(f"Unknown config option: {key}\n") tests/integration/pook_requests_test.py:6 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/integration/pook_requests_test.py:6: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html pytestmark = [pytest.mark.pook] tests/unit/interceptors/base.py:67 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:67: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:83 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:83: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/base.py:99 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:99: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/base.py:125 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:125: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/base.py:157 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:157: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:170 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:170: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:182 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:182: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:197 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:197: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:210 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:210: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:220 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:220: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:230 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:230: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:242 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/base.py:242: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/aiohttp_test.py:8 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:8: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html pytestmark = [pytest.mark.pook] tests/unit/interceptors/aiohttp_test.py:32 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:32: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:42 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:42: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:52 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:52: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:60 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:60: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:69 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:69: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:79 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:79: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:91 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:91: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:105 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/aiohttp_test.py:105: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/httpx_test.py:9 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/httpx_test.py:9: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html pytestmark = [pytest.mark.pook] tests/unit/interceptors/urllib3_test.py:107 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/urllib3_test.py:107: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/urllib_test.py:34 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/urllib_test.py:34: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/urllib_test.py:42 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/interceptors/urllib_test.py:42: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/matchers/query_test.py:14 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/matchers/query_test.py:14: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/matchers/query_test.py:22 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/matchers/query_test.py:22: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/mock_engine_test.py:61 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/mock_engine_test.py:61: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/mock_test.py:150 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build/tests/unit/mock_test.py:150: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/api_test.py: 1 warning tests/unit/interceptors/aiohttp_test.py: 8 warnings tests/unit/interceptors/httpx_test.py: 1 warning /usr/lib/python3/dist-packages/_pytest/python.py:148: PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped. You need to install a suitable plugin for your async framework, for example: - anyio - pytest-asyncio - pytest-tornasync - pytest-trio - pytest-twisted warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid))) -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED tests/integration/examples_test.py::test_examples[aiohttp_client.py] FAILED tests/integration/examples_test.py::test_examples[decorators.py] - Ass... FAILED tests/integration/examples_test.py::test_examples[network_mode.py] - A... FAILED tests/integration/examples_test.py::test_examples[urllib3_client.py] FAILED tests/integration/examples_test.py::test_examples[network_mode_httpx.py] FAILED tests/integration/examples_test.py::test_examples[mock_context_manager.py] FAILED tests/integration/pook_requests_test.py::test_requests_get - requests.... FAILED tests/integration/pook_requests_test.py::test_requests_match_url - req... FAILED tests/integration/pook_requests_test.py::test_requests_match_query_params FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_activate_deactivate FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_network_mode FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_network_mode_hostname FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_multiple_network_filters FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_json_request FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_json_response FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_json_request_and_response FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_header_sent FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_mocked_response_headers FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_mutli_value_headers FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_mutli_value_response_headers FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_activate_deactivate FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_network_mode FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_network_mode_hostname FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_multiple_network_filters FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_json_request FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_json_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_json_request_and_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_header_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_mocked_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_mutli_value_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_mutli_value_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_activate_deactivate FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_network_mode FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_network_mode_hostname FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_multiple_network_filters FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_json_request FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_json_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_json_request_and_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_header_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_mocked_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_mutli_value_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_mutli_value_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/httpx_test.py::test_sync - assert 404 == 200 FAILED tests/unit/interceptors/httpx_test.py::test_json - assert 404 == 200 FAILED tests/unit/interceptors/httpx_test.py::test_streaming[iter_bytes] - As... FAILED tests/unit/interceptors/httpx_test.py::test_streaming[iter_raw] - Asse... FAILED tests/unit/interceptors/httpx_test.py::test_redirect_following - asser... FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_activate_deactivate FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_network_mode FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_network_mode_hostname FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_multiple_network_filters FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_json_request FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_json_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_json_request_and_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_header_sent FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_mocked_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_mutli_value_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_mutli_value_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_activate_deactivate FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_network_mode FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_network_mode_hostname FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_multiple_network_filters FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_json_request FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_json_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_json_request_and_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_header_sent FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_mocked_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_mutli_value_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_mutli_value_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/urllib3_test.py::test_post_with_headers - asse... FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_activate_deactivate FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_network_mode FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_network_mode_hostname FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_multiple_network_filters FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_json_request FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_json_response FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_json_request_and_response FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_header_sent FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_mocked_response_headers FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_mutli_value_headers FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_mutli_value_response_headers FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/urllib_test.py::test_urllib_ssl - urllib.error... FAILED tests/unit/interceptors/urllib_test.py::test_urllib_clear - urllib.err... FAILED tests/unit/matchers/headers_test.py::test_headers_not_matching[Missing request header str expectation] FAILED tests/unit/matchers/headers_test.py::test_headers_not_matching[Missing request header bytes expectation] FAILED tests/unit/matchers/query_test.py::test_param_exists_empty_disallowed FAILED tests/unit/matchers/query_test.py::test_param_exists_empty_allowed - u... FAILED tests/unit/mock_test.py::test_mock_constructor[params] - pook.exceptio... FAILED tests/unit/mock_test.py::test_mock_constructor[param_exists_has_value] ===== 95 failed, 124 passed, 10 skipped, 3 xfailed, 42 warnings in 20.42s ====== E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.12_pook/build; python3.12 -m pytest tests I: pybuild pybuild:308: cp -r /build/reproducible-path/python-pook-2.1.3/examples /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build ; rm -f /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/mocket_example.py I: pybuild base:311: cd /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build; python3.13 -m pytest tests ============================= test session starts ============================== platform linux -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0 rootdir: /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build configfile: pyproject.toml plugins: pook-2.1.3, httpbin-2.1.0, cov-5.0.0, typeguard-4.4.1, anyio-4.7.0 collected 232 items tests/integration/engines_test.py .. [ 0%] tests/integration/examples_test.py F.....F...F...F..F.F... [ 10%] tests/integration/pook_requests_test.py FFF [ 12%] tests/unit/api_test.py ......s [ 15%] tests/unit/engine_test.py .. [ 15%] tests/unit/exceptions_test.py . [ 16%] tests/unit/interceptors/aiohttp_test.py FFFFFFFFFFFFssssssss [ 25%] tests/unit/interceptors/httpx_test.py FFFFFFFFFFFFFFFFFFFFFFFFFsFFFF [ 37%] tests/unit/interceptors/module_test.py . [ 38%] tests/unit/interceptors/urllib3_test.py FFFFFFFFFFFFFFFFFFFFF127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 F127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 FF........ [ 52%] F [ 52%] tests/unit/interceptors/urllib_test.py FF127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 FFFFFFFFFFFF [ 58%] tests/unit/matchers/base_test.py .... [ 60%] tests/unit/matchers/headers_test.py ...........FF............ [ 71%] tests/unit/matchers/query_test.py FF [ 71%] tests/unit/matchers/url_test.py ............................ [ 84%] tests/unit/mock_engine_test.py ....x [ 86%] tests/unit/mock_test.py .FxxF......................... [ 99%] tests/unit/regex_test.py .. [100%] =================================== FAILURES =================================== _______________________ test_examples[aiohttp_client.py] _______________________ example = 'aiohttp_client.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.13', 'examples/aiohttp_client.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stderr call ----------------------------- /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/aiohttp_client.py:30: DeprecationWarning: There is no current event loop loop = asyncio.get_event_loop() Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/aiohttp_client.py", line 31, in loop.run_until_complete(main(loop)) ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ File "/usr/lib/python3.13/asyncio/base_events.py", line 720, in run_until_complete return future.result() ~~~~~~~~~~~~~^^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/aiohttp_client.py", line 28, in main await fetch(session, "http://httpbin.org/ip", bytearray("foo bar", "utf-8")) File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/aiohttp_client.py", line 10, in fetch with async_timeout.timeout(10): ~~~~~~~~~~~~~~~~~~~~~^^^^ TypeError: 'Timeout' object does not support the context manager protocol _________________________ test_examples[decorators.py] _________________________ example = 'decorators.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.13', 'examples/decorators.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- #1 status: 200 #2 status: 204 Is done: True Pending mocks: [] ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( (self._dns_host, self.port), ...<2 lines>... socket_options=self.socket_options, ) File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/socket.py", line 975, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( conn, ...<10 lines>... **response_kw, ) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<6 lines>... enforce_content_length=enforce_content_length, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() ~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/http/client.py", line 1091, in _send_output self.send(msg) ~~~~~~~~~^^^^^ File "/usr/lib/python3.13/http/client.py", line 1035, in send self.connect() ~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ~~~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 667, in send resp = conn.urlopen( method=request.method, ...<9 lines>... chunked=chunked, ) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2] ) File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/400 (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/decorators.py", line 26, in res = requests.get("http://httpbin.org/status/400") File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3/dist-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) File "/usr/lib/python3/dist-packages/requests/adapters.py", line 700, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/400 (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) ________________________ test_examples[network_mode.py] ________________________ example = 'network_mode.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.13', 'examples/network_mode.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- Mock status: 201 ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( (self._dns_host, self.port), ...<2 lines>... socket_options=self.socket_options, ) File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/socket.py", line 975, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( conn, ...<10 lines>... **response_kw, ) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<6 lines>... enforce_content_length=enforce_content_length, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() ~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/http/client.py", line 1091, in _send_output self.send(msg) ~~~~~~~~~^^^^^ File "/usr/lib/python3.13/http/client.py", line 1035, in send self.connect() ~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ~~~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 667, in send resp = conn.urlopen( method=request.method, ...<9 lines>... chunked=chunked, ) File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/pook/interceptors/urllib3.py", line 175, in handler return self._on_request( ~~~~~~~~~~~~~~~~^ urlopen, path, conn, method, url, body=body, headers=headers, **kw ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/pook/interceptors/urllib3.py", line 137, in _on_request return urlopen(pool, method, url, body=body, headers=headers, **kw) File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/pook/interceptors/urllib3.py", line 175, in handler return self._on_request( ~~~~~~~~~~~~~~~~^ urlopen, path, conn, method, url, body=body, headers=headers, **kw ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/pook/interceptors/urllib3.py", line 137, in _on_request return urlopen(pool, method, url, body=body, headers=headers, **kw) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2] ) File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/network_mode.py", line 22, in res = requests.get("http://httpbin.org/ip") File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3/dist-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) File "/usr/lib/python3/dist-packages/requests/adapters.py", line 700, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) _______________________ test_examples[urllib3_client.py] _______________________ example = 'urllib3_client.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.13', 'examples/urllib3_client.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- #1 status: 204 ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( (self._dns_host, self.port), ...<2 lines>... socket_options=self.socket_options, ) File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/socket.py", line 975, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( conn, ...<10 lines>... **response_kw, ) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<6 lines>... enforce_content_length=enforce_content_length, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() ~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/http/client.py", line 1091, in _send_output self.send(msg) ~~~~~~~~~^^^^^ File "/usr/lib/python3.13/http/client.py", line 1035, in send self.connect() ~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ~~~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/urllib3_client.py", line 17, in r = http.request("GET", "http://httpbin.org/status/404") File "/usr/lib/python3/dist-packages/urllib3/_request_methods.py", line 135, in request return self.request_encode_url( ~~~~~~~~~~~~~~~~~~~~~~~^ method, ^^^^^^^ ...<3 lines>... **urlopen_kw, ^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/_request_methods.py", line 182, in request_encode_url return self.urlopen(method, url, **extra_kw) ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/urllib3/poolmanager.py", line 443, in urlopen response = conn.urlopen(method, u.request_uri, **kw) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 873, in urlopen return self.urlopen( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<13 lines>... **response_kw, ^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 873, in urlopen return self.urlopen( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<13 lines>... **response_kw, ^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 873, in urlopen return self.urlopen( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<13 lines>... **response_kw, ^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2] ) File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /status/404 (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) _____________________ test_examples[network_mode_httpx.py] _____________________ example = 'network_mode_httpx.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.13', 'examples/network_mode_httpx.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- Mock status: 201 ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 72, in map_httpcore_exceptions yield File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 236, in handle_request resp = self._pool.handle_request(req) File "/usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py", line 256, in handle_request raise exc from None File "/usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py", line 236, in handle_request response = connection.handle_request( pool_request.request ) File "/usr/lib/python3/dist-packages/httpcore/_sync/connection.py", line 101, in handle_request raise exc File "/usr/lib/python3/dist-packages/httpcore/_sync/connection.py", line 78, in handle_request stream = self._connect(request) File "/usr/lib/python3/dist-packages/httpcore/_sync/connection.py", line 124, in _connect stream = self._network_backend.connect_tcp(**kwargs) File "/usr/lib/python3/dist-packages/httpcore/_backends/sync.py", line 207, in connect_tcp with map_exceptions(exc_map): ~~~~~~~~~~~~~~^^^^^^^^^ File "/usr/lib/python3.13/contextlib.py", line 162, in __exit__ self.gen.throw(value) ~~~~~~~~~~~~~~^^^^^^^ File "/usr/lib/python3/dist-packages/httpcore/_exceptions.py", line 14, in map_exceptions raise to_exc(exc) from exc httpcore.ConnectError: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/network_mode_httpx.py", line 22, in res = httpx.get("http://httpbin.org/ip") File "/usr/lib/python3/dist-packages/httpx/_api.py", line 210, in get return request( "GET", ...<11 lines>... trust_env=trust_env, ) File "/usr/lib/python3/dist-packages/httpx/_api.py", line 118, in request return client.request( ~~~~~~~~~~~~~~^ method=method, ^^^^^^^^^^^^^^ ...<8 lines>... follow_redirects=follow_redirects, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 837, in request return self.send(request, auth=auth, follow_redirects=follow_redirects) ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_client.py", line 926, in send response = self._send_handling_auth( request, ...<2 lines>... history=[], ) File "/usr/lib/python3/dist-packages/httpx/_client.py", line 954, in _send_handling_auth response = self._send_handling_redirects( request, follow_redirects=follow_redirects, history=history, ) File "/usr/lib/python3/dist-packages/httpx/_client.py", line 991, in _send_handling_redirects response = self._send_single_request(request) File "/usr/lib/python3/dist-packages/httpx/_client.py", line 1027, in _send_single_request response = transport.handle_request(request) File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/pook/interceptors/_httpx.py", line 141, in handle_request return transport.handle_request(request) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 235, in handle_request with map_httpcore_exceptions(): ~~~~~~~~~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/contextlib.py", line 162, in __exit__ self.gen.throw(value) ~~~~~~~~~~~~~~^^^^^^^ File "/usr/lib/python3/dist-packages/httpx/_transports/default.py", line 89, in map_httpcore_exceptions raise mapped_exc(message) from exc httpx.ConnectError: [Errno -3] Temporary failure in name resolution ____________________ test_examples[mock_context_manager.py] ____________________ example = 'mock_context_manager.py' @pytest.mark.parametrize("example", examples) def test_examples(example): result = subprocess.run([sys.executable, f"examples/{example}"], check=False) > assert result.returncode == 0, result.stdout E AssertionError: None E assert 1 == 0 E + where 1 = CompletedProcess(args=['/usr/bin/python3.13', 'examples/mock_context_manager.py'], returncode=1).returncode tests/integration/examples_test.py:22: AssertionError ----------------------------- Captured stdout call ----------------------------- #1 Status: 403 #1 Headers: {'pepe': 'lopez', 'Content-Type': 'application/json'} #1 Body: {'error': 'not found'} ---------------- #2 Status: 403 #2 Headers: {'pepe': 'lopez', 'Content-Type': 'application/json'} #2 Body: {'error': 'not found'} ---------------- Mock is done: True Mock matches: 2 Is done: True Pending mocks: [] Unmatched requests: [] ----------------------------- Captured stderr call ----------------------------- Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 199, in _new_conn sock = connection.create_connection( (self._dns_host, self.port), ...<2 lines>... socket_options=self.socket_options, ) File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 60, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/socket.py", line 975, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ socket.gaierror: [Errno -3] Temporary failure in name resolution The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 789, in urlopen response = self._make_request( conn, ...<10 lines>... **response_kw, ) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 495, in _make_request conn.request( ~~~~~~~~~~~~^ method, ^^^^^^^ ...<6 lines>... enforce_content_length=enforce_content_length, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 441, in request self.endheaders() ~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/http/client.py", line 1331, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3.13/http/client.py", line 1091, in _send_output self.send(msg) ~~~~~~~~~^^^^^ File "/usr/lib/python3.13/http/client.py", line 1035, in send self.connect() ~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 279, in connect self.sock = self._new_conn() ~~~~~~~~~~~~~~^^ File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 206, in _new_conn raise NameResolutionError(self.host, self, e) from e urllib3.exceptions.NameResolutionError: : Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/requests/adapters.py", line 667, in send resp = conn.urlopen( method=request.method, ...<9 lines>... chunked=chunked, ) File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 843, in urlopen retries = retries.increment( method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2] ) File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 519, in increment raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/examples/mock_context_manager.py", line 37, in res = requests.get("http://httpbin.org/ip") File "/usr/lib/python3/dist-packages/requests/api.py", line 73, in get return request("get", url, params=params, **kwargs) File "/usr/lib/python3/dist-packages/requests/api.py", line 59, in request return session.request(method=method, url=url, **kwargs) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) File "/usr/lib/python3/dist-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) File "/usr/lib/python3/dist-packages/requests/adapters.py", line 700, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /ip (Caused by NameResolutionError(": Failed to resolve 'httpbin.org' ([Errno -3] Temporary failure in name resolution)")) ______________________________ test_requests_get _______________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'foo.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: def test_requests_get(): body = {"error": "not found"} pook.get("http://foo.com").reply(404).json(body) > res = requests.get("http://foo.com") tests/integration/pook_requests_test.py:13: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/requests/api.py:73: in get return request("get", url, params=params, **kwargs) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError ___________________________ test_requests_match_url ____________________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'foo.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: def test_requests_match_url(): body = {"foo": "bar"} pook.get("http://foo.com").reply(200).json(body) > res = requests.get("http://foo.com") tests/integration/pook_requests_test.py:23: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/requests/api.py:73: in get return request("get", url, params=params, **kwargs) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError _______________________ test_requests_match_query_params _______________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'foo.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/?foo=bar', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query='foo=bar', fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/?foo=bar', response = None error = NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: /?foo=bar (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: def test_requests_match_query_params(): body = {"foo": "bar"} (pook.get("http://foo.com").params({"foo": "bar"}).reply(200).json(body)) > res = requests.get("http://foo.com", params={"foo": "bar"}) tests/integration/pook_requests_test.py:33: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/requests/api.py:73: in get return request("get", url, params=params, **kwargs) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='foo.com', port=80): Max retries exceeded with url: /?foo=bar (Caused by NameResolutionError(": Failed to resolve 'foo.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError _________________ TestStandardAiohttp.test_activate_deactivate _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardAiohttp.test_network_mode _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' url_500 = 'http://127.0.0.1:40727/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardAiohttp.test_network_mode_hostname ________________ self = req = traces = [] timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=30, ceil_threshold=5) async def _create_direct_connection( self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout", *, client_error: Type[Exception] = ClientConnectorError, ) -> Tuple[asyncio.Transport, ResponseHandler]: sslcontext = self._get_ssl_context(req) fingerprint = self._get_fingerprint(req) host = req.url.raw_host assert host is not None # Replace multiple trailing dots with a single one. # A trailing dot is only present for fully-qualified domain names. # See https://github.com/aio-libs/aiohttp/pull/7364. if host.endswith(".."): host = host.rstrip(".") + "." port = req.port assert port is not None try: # Cancelling this lookup should not cancel the underlying lookup # or else the cancel event will get broadcast to all the waiters # across all connections. > hosts = await self._resolve_host(host, port, traces=traces) /usr/lib/python3/dist-packages/aiohttp/connector.py:1335: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/aiohttp/connector.py:989: in _resolve_host return await asyncio.shield(resolved_host_task) /usr/lib/python3/dist-packages/aiohttp/connector.py:1020: in _resolve_host_with_throttle addrs = await self._resolver.resolve(host, port, family=self._family) /usr/lib/python3/dist-packages/aiohttp/resolver.py:38: in resolve infos = await self._loop.getaddrinfo( /usr/lib/python3.13/asyncio/base_events.py:934: in getaddrinfo return await self.run_in_executor( /usr/lib/python3.13/concurrent/futures/thread.py:59: in run result = self.fn(*self.args, **self.kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = type = , proto = 0 flags = def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/base.py:35: in make_request return self.loop.run_until_complete( /usr/lib/python3.13/asyncio/base_events.py:720: in run_until_complete return future.result() tests/unit/interceptors/aiohttp_test.py:16: in amake_request response = await session.request( /usr/lib/python3/dist-packages/aiohttp/client.py:663: in _request conn = await self._connector.connect( /usr/lib/python3/dist-packages/aiohttp/connector.py:538: in connect proto = await self._create_connection(req, traces, timeout) /usr/lib/python3/dist-packages/aiohttp/connector.py:1050: in _create_connection _, proto = await self._create_direct_connection(req, traces, timeout) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = traces = [] timeout = ClientTimeout(total=300, connect=None, sock_read=None, sock_connect=30, ceil_threshold=5) async def _create_direct_connection( self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout", *, client_error: Type[Exception] = ClientConnectorError, ) -> Tuple[asyncio.Transport, ResponseHandler]: sslcontext = self._get_ssl_context(req) fingerprint = self._get_fingerprint(req) host = req.url.raw_host assert host is not None # Replace multiple trailing dots with a single one. # A trailing dot is only present for fully-qualified domain names. # See https://github.com/aio-libs/aiohttp/pull/7364. if host.endswith(".."): host = host.rstrip(".") + "." port = req.port assert port is not None try: # Cancelling this lookup should not cancel the underlying lookup # or else the cancel event will get broadcast to all the waiters # across all connections. hosts = await self._resolve_host(host, port, traces=traces) except OSError as exc: if exc.errno is None and isinstance(exc, asyncio.TimeoutError): raise # in case of proxy it is not ClientProxyConnectionError # it is problem of resolving proxy ip itself > raise ClientConnectorDNSError(req.connection_key, exc) from exc E aiohttp.client_exceptions.ClientConnectorDNSError: Cannot connect to host example.com:80 ssl:default [Temporary failure in name resolution] /usr/lib/python3/dist-packages/aiohttp/connector.py:1341: ClientConnectorDNSError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/401 HTTP/1.1" 401 0 ______________ TestStandardAiohttp.test_multiple_network_filters _______________ self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/401 HTTP/1.1" 401 0 ____________________ TestStandardAiohttp.test_json_request _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardAiohttp.test_json_response ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardAiohttp.test_json_request_and_response ______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 _____________________ TestStandardAiohttp.test_header_sent _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardAiohttp.test_mocked_response_headers _______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:46] "GET /status/404 HTTP/1.1" 404 0 _________________ TestStandardAiohttp.test_mutli_value_headers _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardAiohttp.test_mutli_value_response_headers _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardAiohttp.test_unmatched_headers_none_sent _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardAsyncHttpx.test_activate_deactivate ________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardAsyncHttpx.test_network_mode ___________________ self = url_404 = 'http://127.0.0.1:40727/status/404' url_500 = 'http://127.0.0.1:40727/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardAsyncHttpx.test_network_mode_hostname _______________ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: > yield /usr/lib/python3/dist-packages/httpx/_transports/default.py:72: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/httpx/_transports/default.py:377: in handle_async_request resp = await self._pool.handle_async_request(req) /usr/lib/python3/dist-packages/httpcore/_async/connection_pool.py:256: in handle_async_request raise exc from None /usr/lib/python3/dist-packages/httpcore/_async/connection_pool.py:236: in handle_async_request response = await connection.handle_async_request( /usr/lib/python3/dist-packages/httpcore/_async/connection.py:101: in handle_async_request raise exc /usr/lib/python3/dist-packages/httpcore/_async/connection.py:78: in handle_async_request stream = await self._connect(request) /usr/lib/python3/dist-packages/httpcore/_async/connection.py:124: in _connect stream = await self._network_backend.connect_tcp(**kwargs) /usr/lib/python3/dist-packages/httpcore/_backends/auto.py:31: in connect_tcp return await self._backend.connect_tcp( /usr/lib/python3/dist-packages/httpcore/_backends/anyio.py:113: in connect_tcp with map_exceptions(exc_map): /usr/lib/python3.13/contextlib.py:162: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ map = {: , : , : } @contextlib.contextmanager def map_exceptions(map: ExceptionMapping) -> typing.Iterator[None]: try: yield except Exception as exc: # noqa: PIE786 for from_exc, to_exc in map.items(): if isinstance(exc, from_exc): > raise to_exc(exc) from exc E httpcore.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpcore/_exceptions.py:14: ConnectError The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/base.py:35: in make_request return self.loop.run_until_complete( /usr/lib/python3.13/asyncio/base_events.py:720: in run_until_complete return future.result() tests/unit/interceptors/httpx_test.py:17: in amake_request response = await client.request( /usr/lib/python3/dist-packages/httpx/_client.py:1585: in request return await self.send(request, auth=auth, follow_redirects=follow_redirects) /usr/lib/python3/dist-packages/httpx/_client.py:1674: in send response = await self._send_handling_auth( /usr/lib/python3/dist-packages/httpx/_client.py:1702: in _send_handling_auth response = await self._send_handling_redirects( /usr/lib/python3/dist-packages/httpx/_client.py:1739: in _send_handling_redirects response = await self._send_single_request(request) /usr/lib/python3/dist-packages/httpx/_client.py:1776: in _send_single_request response = await transport.handle_async_request(request) /usr/lib/python3/dist-packages/httpx/_transports/default.py:376: in handle_async_request with map_httpcore_exceptions(): /usr/lib/python3.13/contextlib.py:162: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: yield except Exception as exc: mapped_exc = None for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): if not isinstance(exc, from_exc): continue # We want to map to the most specific exception we can find. # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to # `httpx.ReadTimeout`, not just `httpx.TimeoutException`. if mapped_exc is None or issubclass(to_exc, mapped_exc): mapped_exc = to_exc if mapped_exc is None: # pragma: no cover raise message = str(exc) > raise mapped_exc(message) from exc E httpx.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpx/_transports/default.py:89: ConnectError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/401 HTTP/1.1" 401 0 _____________ TestStandardAsyncHttpx.test_multiple_network_filters _____________ self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/401 HTTP/1.1" 401 0 ___________________ TestStandardAsyncHttpx.test_json_request ___________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 __________________ TestStandardAsyncHttpx.test_json_response ___________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardAsyncHttpx.test_json_request_and_response _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardAsyncHttpx.test_header_sent ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardAsyncHttpx.test_mocked_response_headers ______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:47] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardAsyncHttpx.test_mutli_value_headers ________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________ TestStandardAsyncHttpx.test_mutli_value_response_headers ___________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________ TestStandardAsyncHttpx.test_unmatched_headers_none_sent ____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardSyncHttpx.test_activate_deactivate ________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardSyncHttpx.test_network_mode ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' url_500 = 'http://127.0.0.1:40727/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardSyncHttpx.test_network_mode_hostname _______________ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: > yield /usr/lib/python3/dist-packages/httpx/_transports/default.py:72: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/httpx/_transports/default.py:236: in handle_request resp = self._pool.handle_request(req) /usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py:256: in handle_request raise exc from None /usr/lib/python3/dist-packages/httpcore/_sync/connection_pool.py:236: in handle_request response = connection.handle_request( /usr/lib/python3/dist-packages/httpcore/_sync/connection.py:101: in handle_request raise exc /usr/lib/python3/dist-packages/httpcore/_sync/connection.py:78: in handle_request stream = self._connect(request) /usr/lib/python3/dist-packages/httpcore/_sync/connection.py:124: in _connect stream = self._network_backend.connect_tcp(**kwargs) /usr/lib/python3/dist-packages/httpcore/_backends/sync.py:207: in connect_tcp with map_exceptions(exc_map): /usr/lib/python3.13/contextlib.py:162: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ map = {: , : } @contextlib.contextmanager def map_exceptions(map: ExceptionMapping) -> typing.Iterator[None]: try: yield except Exception as exc: # noqa: PIE786 for from_exc, to_exc in map.items(): if isinstance(exc, from_exc): > raise to_exc(exc) from exc E httpcore.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpcore/_exceptions.py:14: ConnectError The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/httpx_test.py:26: in make_request response = httpx.request( /usr/lib/python3/dist-packages/httpx/_api.py:118: in request return client.request( /usr/lib/python3/dist-packages/httpx/_client.py:837: in request return self.send(request, auth=auth, follow_redirects=follow_redirects) /usr/lib/python3/dist-packages/httpx/_client.py:926: in send response = self._send_handling_auth( /usr/lib/python3/dist-packages/httpx/_client.py:954: in _send_handling_auth response = self._send_handling_redirects( /usr/lib/python3/dist-packages/httpx/_client.py:991: in _send_handling_redirects response = self._send_single_request(request) /usr/lib/python3/dist-packages/httpx/_client.py:1027: in _send_single_request response = transport.handle_request(request) /usr/lib/python3/dist-packages/httpx/_transports/default.py:235: in handle_request with map_httpcore_exceptions(): /usr/lib/python3.13/contextlib.py:162: in __exit__ self.gen.throw(value) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @contextlib.contextmanager def map_httpcore_exceptions() -> typing.Iterator[None]: try: yield except Exception as exc: mapped_exc = None for from_exc, to_exc in HTTPCORE_EXC_MAP.items(): if not isinstance(exc, from_exc): continue # We want to map to the most specific exception we can find. # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to # `httpx.ReadTimeout`, not just `httpx.TimeoutException`. if mapped_exc is None or issubclass(to_exc, mapped_exc): mapped_exc = to_exc if mapped_exc is None: # pragma: no cover raise message = str(exc) > raise mapped_exc(message) from exc E httpx.ConnectError: [Errno -3] Temporary failure in name resolution /usr/lib/python3/dist-packages/httpx/_transports/default.py:89: ConnectError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/401 HTTP/1.1" 401 0 _____________ TestStandardSyncHttpx.test_multiple_network_filters ______________ self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/401 HTTP/1.1" 401 0 ___________________ TestStandardSyncHttpx.test_json_request ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardSyncHttpx.test_json_response ___________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardSyncHttpx.test_json_request_and_response _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardSyncHttpx.test_header_sent ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardSyncHttpx.test_mocked_response_headers ______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardSyncHttpx.test_mutli_value_headers ________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________ TestStandardSyncHttpx.test_mutli_value_response_headers ____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardSyncHttpx.test_unmatched_headers_none_sent ____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 __________________________________ test_sync ___________________________________ URL = 'http://127.0.0.1:40727/status/404' def test_sync(URL): pook.get(URL).times(1).reply(200).body("123") response = httpx.get(URL) > assert response.status_code == 200 E assert 404 == 200 E + where 404 = .status_code tests/unit/interceptors/httpx_test.py:43: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 __________________________________ test_json ___________________________________ URL = 'http://127.0.0.1:40727/status/404' def test_json(URL): ( pook.post(URL) .times(1) .json({"id": "123abc"}) .reply(200) .json({"title": "123abc title"}) ) response = httpx.post(URL, json={"id": "123abc"}) > assert response.status_code == 200 E assert 404 == 200 E + where 404 = .status_code tests/unit/interceptors/httpx_test.py:67: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "POST /status/404 HTTP/1.1" 404 0 __________________________ test_streaming[iter_bytes] __________________________ URL = 'http://127.0.0.1:40727/status/404', response_method = 'iter_bytes' @pytest.mark.parametrize("response_method", ("iter_bytes", "iter_raw")) def test_streaming(URL, response_method): streamed_response = b"streamed response" pook.get(URL).times(1).reply(200).body(streamed_response).mock with httpx.stream("GET", URL) as r: read_bytes = list(getattr(r, response_method)(chunk_size=1)) > assert len(read_bytes) == len(streamed_response) E AssertionError: assert 0 == 17 E + where 0 = len([]) E + and 17 = len(b'streamed response') tests/unit/interceptors/httpx_test.py:79: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________________________ test_streaming[iter_raw] ___________________________ URL = 'http://127.0.0.1:40727/status/404', response_method = 'iter_raw' @pytest.mark.parametrize("response_method", ("iter_bytes", "iter_raw")) def test_streaming(URL, response_method): streamed_response = b"streamed response" pook.get(URL).times(1).reply(200).body(streamed_response).mock with httpx.stream("GET", URL) as r: read_bytes = list(getattr(r, response_method)(chunk_size=1)) > assert len(read_bytes) == len(streamed_response) E AssertionError: assert 0 == 17 E + where 0 = len([]) E + and 17 = len(b'streamed response') tests/unit/interceptors/httpx_test.py:79: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ___________________________ test_redirect_following ____________________________ URL = 'http://127.0.0.1:40727/status/404' def test_redirect_following(URL): urls = [URL, f"{URL}/redirected", f"{URL}/redirected_again"] for req, dest in zip_longest(urls, urls[1:], fillvalue=None): if not dest: pook.get(req).times(1).reply(200).body("found at last") else: pook.get(req).times(1).reply(302).header("Location", dest) response = httpx.get(URL, follow_redirects=True) > assert response.status_code == 200 E assert 404 == 200 E + where 404 = .status_code tests/unit/interceptors/httpx_test.py:93: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 _________________ TestStandardUrllib3.test_activate_deactivate _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardUrllib3.test_network_mode _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' url_500 = 'http://127.0.0.1:40727/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardUrllib3.test_network_mode_hostname ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None, headers = {} retries = Retry(total=0, connect=None, read=None, redirect=None, status=None) redirect = False, assert_same_host = False, timeout = <_TYPE_DEFAULT.token: -1> pool_timeout = None, release_conn = True, chunked = False, body_pos = None preload_content = True, decode_content = True, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/urllib3_test.py:21: in make_request response = http.request(method, url, content, headers=req_headers) /usr/lib/python3/dist-packages/urllib3/_request_methods.py:135: in request return self.request_encode_url( /usr/lib/python3/dist-packages/urllib3/_request_methods.py:182: in request_encode_url return self.urlopen(method, url, **extra_kw) /usr/lib/python3/dist-packages/urllib3/poolmanager.py:443: in urlopen response = conn.urlopen(method, u.request_uri, **kw) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:873: in urlopen return self.urlopen( /usr/lib/python3/dist-packages/urllib3/connectionpool.py:873: in urlopen return self.urlopen( /usr/lib/python3/dist-packages/urllib3/connectionpool.py:873: in urlopen return self.urlopen( /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=None, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='example.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:48] "GET /status/401 HTTP/1.1" 401 0 ------------------------------ Captured log call ------------------------------- WARNING urllib3.connectionpool:connectionpool.py:870 Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")': / WARNING urllib3.connectionpool:connectionpool.py:870 Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")': / WARNING urllib3.connectionpool:connectionpool.py:870 Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")': / ______________ TestStandardUrllib3.test_multiple_network_filters _______________ self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 ____________________ TestStandardUrllib3.test_json_request _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardUrllib3.test_json_response ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardUrllib3.test_json_request_and_response ______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _____________________ TestStandardUrllib3.test_header_sent _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardUrllib3.test_mocked_response_headers _______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _________________ TestStandardUrllib3.test_mutli_value_headers _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ____________ TestStandardUrllib3.test_mutli_value_response_headers _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardUrllib3.test_unmatched_headers_none_sent _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardRequests.test_activate_deactivate _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardRequests.test_network_mode ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' url_500 = 'http://127.0.0.1:40727/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _______________ TestStandardRequests.test_network_mode_hostname ________________ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: > sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) /usr/lib/python3/dist-packages/urllib3/connection.py:199: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/util/connection.py:60: in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = type = , proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror The above exception was the direct cause of the following exception: self = method = 'GET', url = '/', body = None headers = {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'} retries = Retry(total=0, connect=None, read=False, redirect=None, status=None) redirect = False, assert_same_host = False timeout = Timeout(connect=None, read=None, total=None), pool_timeout = None release_conn = False, chunked = False, body_pos = None, preload_content = False decode_content = False, response_kw = {} parsed_url = Url(scheme=None, auth=None, host=None, port=None, path='/', query=None, fragment=None) destination_scheme = None, conn = None, release_this_conn = True http_tunnel_required = False, err = None, clean_exit = False def urlopen( # type: ignore[override] self, method: str, url: str, body: _TYPE_BODY | None = None, headers: typing.Mapping[str, str] | None = None, retries: Retry | bool | int | None = None, redirect: bool = True, assert_same_host: bool = True, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, pool_timeout: int | None = None, release_conn: bool | None = None, chunked: bool = False, body_pos: _TYPE_BODY_POSITION | None = None, preload_content: bool = True, decode_content: bool = True, **response_kw: typing.Any, ) -> BaseHTTPResponse: """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all the raw details. .. note:: More commonly, it's appropriate to use a convenience method such as :meth:`request`. .. note:: `release_conn` will only behave as expected if `preload_content=False` because we want to make `preload_content=False` the default behaviour someday soon without breaking backwards compatibility. :param method: HTTP request method (such as GET, POST, PUT, etc.) :param url: The URL to perform the request on. :param body: Data to send in the request body, either :class:`str`, :class:`bytes`, an iterable of :class:`str`/:class:`bytes`, or a file-like object. :param headers: Dictionary of custom headers to send, such as User-Agent, If-None-Match, etc. If None, pool headers are used. If provided, these headers completely replace any pool-specific headers. :param retries: Configure the number of retries to allow before raising a :class:`~urllib3.exceptions.MaxRetryError` exception. If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a :class:`~urllib3.util.retry.Retry` object for fine-grained control over different types of retries. Pass an integer number to retry connection errors that many times, but no other types of errors. Pass zero to never retry. If ``False``, then retries are disabled and any exception is raised immediately. Also, instead of raising a MaxRetryError on redirects, the redirect response will be returned. :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. :param redirect: If True, automatically handle redirects (status codes 301, 302, 303, 307, 308). Each redirect counts as a retry. Disabling retries will disable redirect, too. :param assert_same_host: If ``True``, will make sure that the host of the pool requests is consistent else will raise HostChangedError. When ``False``, you can use the pool on an HTTP proxy and request foreign hosts. :param timeout: If specified, overrides the default timeout for this one request. It may be a float (in seconds) or an instance of :class:`urllib3.util.Timeout`. :param pool_timeout: If set and the pool is set to block=True, then this method will block for ``pool_timeout`` seconds and raise EmptyPoolError if no connection is available within the time period. :param bool preload_content: If True, the response's body will be preloaded into memory. :param bool decode_content: If True, will attempt to decode the body based on the 'content-encoding' header. :param release_conn: If False, then the urlopen call will not release the connection back into the pool once a response is received (but will release if you read the entire contents of the response such as when `preload_content=True`). This is useful if you're not preloading the response's content immediately. You will need to call ``r.release_conn()`` on the response ``r`` to return the connection back into the pool. If None, it takes the value of ``preload_content`` which defaults to ``True``. :param bool chunked: If True, urllib3 will send the body using chunked transfer encoding. Otherwise, urllib3 will send the body using the standard content-length form. Defaults to False. :param int body_pos: Position to seek to in file-like body in the event of a retry or redirect. Typically this won't need to be set because urllib3 will auto-populate the value when needed. """ parsed_url = parse_url(url) destination_scheme = parsed_url.scheme if headers is None: headers = self.headers if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: release_conn = preload_content # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) # Ensure that the URL we're connecting to is properly encoded if url.startswith("/"): url = to_str(_encode_target(url)) else: url = to_str(parsed_url.url) conn = None # Track whether `conn` needs to be released before # returning/raising/recursing. Update this variable if necessary, and # leave `release_conn` constant throughout the function. That way, if # the function recurses, the original value of `release_conn` will be # passed down into the recursive call, and its value will be respected. # # See issue #651 [1] for details. # # [1] release_this_conn = release_conn http_tunnel_required = connection_requires_http_tunnel( self.proxy, self.proxy_config, destination_scheme ) # Merge the proxy headers. Only done when not using HTTP CONNECT. We # have to copy the headers dict so we can safely change it without those # changes being reflected in anyone else's copy. if not http_tunnel_required: headers = headers.copy() # type: ignore[attr-defined] headers.update(self.proxy_headers) # type: ignore[union-attr] # Must keep the exception bound to a separate variable or else Python 3 # complains about UnboundLocalError. err = None # Keep track of whether we cleanly exited the except block. This # ensures we do proper cleanup in finally. clean_exit = False # Rewind body position, if needed. Record current position # for future rewinds in the event of a redirect/retry. body_pos = set_file_position(body, body_pos) try: # Request a connection from the queue. timeout_obj = self._get_timeout(timeout) conn = self._get_conn(timeout=pool_timeout) conn.timeout = timeout_obj.connect_timeout # type: ignore[assignment] # Is this a closed/new connection that requires CONNECT tunnelling? if self.proxy is not None and http_tunnel_required and conn.is_closed: try: self._prepare_proxy(conn) except (BaseSSLError, OSError, SocketTimeout) as e: self._raise_timeout( err=e, url=self.proxy.url, timeout_value=conn.timeout ) raise # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise # it will also try to release it and we'll have a double-release # mess. response_conn = conn if not release_conn else None # Make the request on the HTTPConnection object > response = self._make_request( conn, method, url, timeout=timeout_obj, body=body, headers=headers, chunked=chunked, retries=retries, response_conn=response_conn, preload_content=preload_content, decode_content=decode_content, **response_kw, ) /usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:495: in _make_request conn.request( /usr/lib/python3/dist-packages/urllib3/connection.py:441: in request self.endheaders() /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3/dist-packages/urllib3/connection.py:279: in connect self.sock = self._new_conn() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def _new_conn(self) -> socket.socket: """Establish a socket connection and set nodelay settings on it. :return: New socket connection. """ try: sock = connection.create_connection( (self._dns_host, self.port), self.timeout, source_address=self.source_address, socket_options=self.socket_options, ) except socket.gaierror as e: > raise NameResolutionError(self.host, self, e) from e E urllib3.exceptions.NameResolutionError: : Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution) /usr/lib/python3/dist-packages/urllib3/connection.py:206: NameResolutionError The above exception was the direct cause of the following exception: self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: > resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) /usr/lib/python3/dist-packages/requests/adapters.py:667: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen retries = retries.increment( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Retry(total=0, connect=None, read=False, redirect=None, status=None) method = 'GET', url = '/', response = None error = NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)") _pool = _stacktrace = def increment( self, method: str | None = None, url: str | None = None, response: BaseHTTPResponse | None = None, error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not return a response. :type response: :class:`~urllib3.response.BaseHTTPResponse` :param Exception error: An error encountered during the request, or None if the response was received successfully. :return: A new ``Retry`` object. """ if self.total is False and error: # Disabled, indicate to re-raise the error. raise reraise(type(error), error, _stacktrace) total = self.total if total is not None: total -= 1 connect = self.connect read = self.read redirect = self.redirect status_count = self.status other = self.other cause = "unknown" status = None redirect_location = None if error and self._is_connection_error(error): # Connect retry? if connect is False: raise reraise(type(error), error, _stacktrace) elif connect is not None: connect -= 1 elif error and self._is_read_error(error): # Read retry? if read is False or method is None or not self._is_method_retryable(method): raise reraise(type(error), error, _stacktrace) elif read is not None: read -= 1 elif error: # Other retry? if other is not None: other -= 1 elif response and response.get_redirect_location(): # Redirect retry? if redirect is not None: redirect -= 1 cause = "too many redirects" response_redirect_location = response.get_redirect_location() if response_redirect_location: redirect_location = response_redirect_location status = response.status else: # Incrementing because of a server error like a 500 in # status_forcelist and the given method is in the allowed_methods cause = ResponseError.GENERIC_ERROR if response and response.status: if status_count is not None: status_count -= 1 cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status history = self.history + ( RequestHistory(method, url, error, status, redirect_location), ) new_retry = self.new( total=total, connect=connect, read=read, redirect=redirect, status=status_count, other=other, history=history, ) if new_retry.is_exhausted(): reason = error or ResponseError(cause) > raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type] E urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='example.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError During handling of the above exception, another exception occurred: self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/urllib3_test.py:35: in make_request response = requests.request(method, url, data=content, headers=req_headers) /usr/lib/python3/dist-packages/requests/api.py:59: in request return session.request(method=method, url=url, **kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:589: in request resp = self.send(prep, **send_kwargs) /usr/lib/python3/dist-packages/requests/sessions.py:703: in send r = adapter.send(request, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = request = , stream = False timeout = Timeout(connect=None, read=None, total=None), verify = True cert = None proxies = OrderedDict({'no': 'localhost', 'https': 'https://127.0.0.1:9/'}) def send( self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None ): """Sends PreparedRequest object. Returns Response object. :param request: The :class:`PreparedRequest ` being sent. :param stream: (optional) Whether to stream the request content. :param timeout: (optional) How long to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) ` tuple. :type timeout: float or tuple or urllib3 Timeout object :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use :param cert: (optional) Any user-provided SSL certificate to be trusted. :param proxies: (optional) The proxies dictionary to apply to the request. :rtype: requests.Response """ try: conn = self.get_connection_with_tls_context( request, verify, proxies=proxies, cert=cert ) except LocationValueError as e: raise InvalidURL(e, request=request) self.cert_verify(conn, request.url, verify, cert) url = self.request_url(request, proxies) self.add_headers( request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies, ) chunked = not (request.body is None or "Content-Length" in request.headers) if isinstance(timeout, tuple): try: connect, read = timeout timeout = TimeoutSauce(connect=connect, read=read) except ValueError: raise ValueError( f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, " f"or a single float to set both timeouts to the same value." ) elif isinstance(timeout, TimeoutSauce): pass else: timeout = TimeoutSauce(connect=timeout, read=timeout) try: resp = conn.urlopen( method=request.method, url=url, body=request.body, headers=request.headers, redirect=False, assert_same_host=False, preload_content=False, decode_content=False, retries=self.max_retries, timeout=timeout, chunked=chunked, ) except (ProtocolError, OSError) as err: raise ConnectionError(err, request=request) except MaxRetryError as e: if isinstance(e.reason, ConnectTimeoutError): # TODO: Remove this in 3.0.0: see #2811 if not isinstance(e.reason, NewConnectionError): raise ConnectTimeout(e, request=request) if isinstance(e.reason, ResponseError): raise RetryError(e, request=request) if isinstance(e.reason, _ProxyError): raise ProxyError(e, request=request) if isinstance(e.reason, _SSLError): # This branch is for urllib3 v1.22 and later. raise SSLError(e, request=request) > raise ConnectionError(e, request=request) E requests.exceptions.ConnectionError: HTTPConnectionPool(host='example.com', port=80): Max retries exceeded with url: / (Caused by NameResolutionError(": Failed to resolve 'example.com' ([Errno -3] Temporary failure in name resolution)")) /usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 ______________ TestStandardRequests.test_multiple_network_filters ______________ self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/401 HTTP/1.1" 401 0 ____________________ TestStandardRequests.test_json_request ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestStandardRequests.test_json_response ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _____________ TestStandardRequests.test_json_request_and_response ______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestStandardRequests.test_header_sent _____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) status, body, _ = self.make_request("GET", url_404, headers=headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:207: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ______________ TestStandardRequests.test_mocked_response_headers _______________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:217: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ________________ TestStandardRequests.test_mutli_value_headers _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ____________ TestStandardRequests.test_mutli_value_response_headers ____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) status, _, headers = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:239: AssertionError ____________ TestStandardRequests.test_unmatched_headers_none_sent _____________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ____________________________ test_post_with_headers ____________________________ URL = 'http://127.0.0.1:40727/foo' @pytest.mark.pook def test_post_with_headers(URL): mock = pook.post(URL).header("k", "v").reply(200).mock http = urllib3.PoolManager(headers={"k": "v"}) resp = http.request("POST", URL) > assert resp.status == 200 E assert 404 == 200 E + where 404 = .status tests/unit/interceptors/urllib3_test.py:112: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "POST /foo HTTP/1.1" 404 207 _____________________ TestUrllib.test_activate_deactivate ______________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_activate_deactivate(self, url_404): """Deactivating pook allows requests to go through.""" pook.get(url_404).reply(200).body("hello from pook") status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:74: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 _________________________ TestUrllib.test_network_mode _________________________ self = url_404 = 'http://127.0.0.1:40727/status/404' url_500 = 'http://127.0.0.1:40727/status/500' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode(self, url_404, url_500): """Enabling network mode allows requests to pass through even if no mock is matched.""" pook.get(url_404).reply(200).body("hello from pook") pook.enable_network() # Avoid matching the mocks status, *_ = self.make_request("POST", url_500) assert status == 500 mocked_status, mocked_body, *_ = self.make_request("GET", url_404) > assert mocked_status == 200 E AssertionError tests/unit/interceptors/base.py:96: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:49] "POST /status/500 HTTP/1.1" 500 0 127.0.0.1 - - [12/Feb/2026 23:17:49] "GET /status/404 HTTP/1.1" 404 0 ____________________ TestUrllib.test_network_mode_hostname _____________________ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.13'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: > h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.13/urllib/request.py:1319: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/http/client.py:1336: in request self._send_request(method, url, body, headers, encode_chunked) /usr/lib/python3.13/http/client.py:1382: in _send_request self.endheaders(body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3.13/http/client.py:1001: in connect self.sock = self._create_connection( /usr/lib/python3.13/socket.py:840: in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = 0, type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror During handling of the above exception, another exception occurred: self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_network_mode_hostname(self, url_401): example_com = "http://example.com" pook.get(example_com).header("x-pook", "1").reply(200).body("hello from pook") # httpbin runs on loopback pook.enable_network("127.0.0.1") httpbin_status, *_ = self.make_request("GET", url_401) # network is enabled for httpbin hostname so it goes through assert httpbin_status == 401 with pytest.raises(PookNoMatches): # Make the request without query params to avoid matching the mock # which should raise a no match exception, as network mode is not enabled # for example.com hostname > self.make_request("GET", example_com) tests/unit/interceptors/base.py:115: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/unit/interceptors/urllib_test.py:28: in make_request response: HTTPResponse = urlopen(request) /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:489: in open response = self._open(req, data) /usr/lib/python3.13/urllib/request.py:506: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) /usr/lib/python3.13/urllib/request.py:1348: in http_open return self.do_open(http.client.HTTPConnection, req) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.13'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error > raise URLError(err) E urllib.error.URLError: /usr/lib/python3.13/urllib/request.py:1322: URLError ___________________ TestUrllib.test_multiple_network_filters ___________________ self = url_401 = 'http://127.0.0.1:40727/status/401' @pytest.mark.pook(allow_pending_mocks=True) def test_multiple_network_filters(self, url_401): """When multiple network filters are added, only one is required to match for the request to be allowed through the network.""" def has_x_header(request: pook.Request): return request.headers.get("x-pook") == "x" def has_y_header(request: pook.Request): return request.headers.get("x-pook") == "y" pook.enable_network() pook.use_network_filter(has_x_header, has_y_header) pook.get(url_401).header("x-pook", "z").reply(200).body("hello from pook") # Network filter matches, so request is allowed despite not matching a mock x_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "x")]) assert x_status == 401 # Network filter matches, so request is allowed despite not matching a mock y_status, *_ = self.make_request("GET", url_401, headers=[("x-pook", "y")]) assert y_status == 401 # Mock matches, so the response is mocked z_status, z_body, *_ = self.make_request( "GET", url_401, headers=[("x-pook", "z")] ) > assert z_status == 200 E AssertionError tests/unit/interceptors/base.py:154: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/401 HTTP/1.1" 401 0 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/401 HTTP/1.1" 401 0 _________________________ TestUrllib.test_json_request _________________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request(self, url_404): """JSON request bodies are correctly matched.""" json_request = {"hello": "json-request"} pook.get(url_404).json(json_request).reply(200).body("hello from pook") status, body, *_ = self.make_request( "GET", url_404, json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:167: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 ________________________ TestUrllib.test_json_response _________________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_response(self, url_404): """JSON responses are correctly mocked.""" json_response = {"hello": "json-request"} pook.get(url_404).reply(200).json(json_response) status, body, *_ = self.make_request("GET", url_404) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:178: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 __________________ TestUrllib.test_json_request_and_response ___________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_json_request_and_response(self, url_404): """JSON requests and responses do not interfere with each other.""" json_request = {"id": "123abc"} json_response = {"title": "123abc title"} pook.get(url_404).json(json_request).reply(200).json(json_response) status, body, *_ = self.make_request( "GET", url_404, content=json.dumps(json_request).encode() ) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:193: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 _________________________ TestUrllib.test_header_sent __________________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_header_sent(self, url_404): """Sent headers can be matched.""" headers = [("x-hello", "from pook")] pook.get(url_404).header("x-hello", "from pook").reply(200).body( "hello from pook" ) > status, body, _ = self.make_request("GET", url_404, headers=headers) E ValueError: not enough values to unpack (expected 3, got 2) tests/unit/interceptors/base.py:205: ValueError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 ___________________ TestUrllib.test_mocked_response_headers ____________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mocked_response_headers(self, url_404): """Mocked response headers are appropriately returned.""" pook.get(url_404).reply(200).header("x-hello", "from pook") > status, _, headers = self.make_request("GET", url_404) E ValueError: not enough values to unpack (expected 3, got 2) tests/unit/interceptors/base.py:215: ValueError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 _____________________ TestUrllib.test_mutli_value_headers ______________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_headers(self, url_404): """Multi-value headers can be matched.""" match_headers = [("x-hello", "from pook"), ("x-hello", "another time")] pook.get(url_404).header("x-hello", "from pook, another time").reply(200) status, *_ = self.make_request("GET", url_404, headers=match_headers) > assert status == 200 E AssertionError tests/unit/interceptors/base.py:228: AssertionError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 _________________ TestUrllib.test_mutli_value_response_headers _________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_mutli_value_response_headers(self, url_404): """Multi-value response headers can be mocked.""" pook.get(url_404).reply(200).header("x-hello", "from pook").header( "x-hello", "another time" ) > status, _, headers = self.make_request("GET", url_404) E ValueError: not enough values to unpack (expected 3, got 2) tests/unit/interceptors/base.py:237: ValueError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 _________________ TestUrllib.test_unmatched_headers_none_sent __________________ self = url_404 = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_unmatched_headers_none_sent(self, url_404): """Header matching will run, but not match, on requests that send no headers.""" pook.get(url_404).header("x-hello", "from pook").reply(200) > with pytest.raises(PookNoMatches): E Failed: DID NOT RAISE tests/unit/interceptors/base.py:247: Failed ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404 HTTP/1.1" 404 0 _______________________________ test_urllib_ssl ________________________________ self = http_class = req = http_conn_args = {'context': } host = '127.0.0.1:9', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.13'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: > h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.13/urllib/request.py:1319: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/http/client.py:1336: in request self._send_request(method, url, body, headers, encode_chunked) /usr/lib/python3.13/http/client.py:1382: in _send_request self.endheaders(body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3.13/http/client.py:1470: in connect super().connect() /usr/lib/python3.13/http/client.py:1001: in connect self.sock = self._create_connection( /usr/lib/python3.13/socket.py:864: in create_connection raise exceptions[0] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ address = ('127.0.0.1', 9), timeout = source_address = None def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None, *, all_errors=False): """Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, port)``) and return the socket object. Passing the optional *timeout* parameter will set the timeout on the socket instance before attempting to connect. If no *timeout* is supplied, the global default timeout setting returned by :func:`getdefaulttimeout` is used. If *source_address* is set it must be a tuple of (host, port) for the socket to bind as a source address before making the connection. A host of '' or port 0 tells the OS to use the default. When a connection cannot be created, raises the last error if *all_errors* is False, and an ExceptionGroup of all errors if *all_errors* is True. """ host, port = address exceptions = [] for res in getaddrinfo(host, port, 0, SOCK_STREAM): af, socktype, proto, canonname, sa = res sock = None try: sock = socket(af, socktype, proto) if timeout is not _GLOBAL_DEFAULT_TIMEOUT: sock.settimeout(timeout) if source_address: sock.bind(source_address) > sock.connect(sa) E ConnectionRefusedError: [Errno 111] Connection refused /usr/lib/python3.13/socket.py:849: ConnectionRefusedError During handling of the above exception, another exception occurred: @pytest.mark.pook def test_urllib_ssl(): pook.get("https://example.com").reply(200).body("Hello from pook") > res = urlopen("https://example.com") tests/unit/interceptors/urllib_test.py:37: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:489: in open response = self._open(req, data) /usr/lib/python3.13/urllib/request.py:506: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) /usr/lib/python3.13/urllib/request.py:1367: in https_open return self.do_open(http.client.HTTPSConnection, req, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = http_conn_args = {'context': } host = '127.0.0.1:9', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.13'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error > raise URLError(err) E urllib.error.URLError: /usr/lib/python3.13/urllib/request.py:1322: URLError ______________________________ test_urllib_clear _______________________________ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.13'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: > h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) /usr/lib/python3.13/urllib/request.py:1319: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/http/client.py:1336: in request self._send_request(method, url, body, headers, encode_chunked) /usr/lib/python3.13/http/client.py:1382: in _send_request self.endheaders(body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1331: in endheaders self._send_output(message_body, encode_chunked=encode_chunked) /usr/lib/python3.13/http/client.py:1091: in _send_output self.send(msg) /usr/lib/python3.13/http/client.py:1035: in send self.connect() /usr/lib/python3.13/http/client.py:1001: in connect self.sock = self._create_connection( /usr/lib/python3.13/socket.py:840: in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ host = 'example.com', port = 80, family = 0, type = proto = 0, flags = 0 def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): """Resolve host and port into list of address info entries. Translate the host/port argument into a sequence of 5-tuples that contain all the necessary arguments for creating a socket connected to that service. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. By passing None as the value of host and port, you can pass NULL to the underlying C API. The family, type and proto arguments can be optionally specified in order to narrow the list of addresses returned. Passing zero as a value for each of these arguments selects the full range of results. """ # We override this function since we want to translate the numeric family # and socket type values to enum constants. addrlist = [] > for res in _socket.getaddrinfo(host, port, family, type, proto, flags): E socket.gaierror: [Errno -3] Temporary failure in name resolution /usr/lib/python3.13/socket.py:975: gaierror During handling of the above exception, another exception occurred: @pytest.mark.pook def test_urllib_clear(): pook.get("http://example.com").reply(200).body("Hello from pook") > res = urlopen("http://example.com") tests/unit/interceptors/urllib_test.py:45: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:489: in open response = self._open(req, data) /usr/lib/python3.13/urllib/request.py:506: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) /usr/lib/python3.13/urllib/request.py:1348: in http_open return self.do_open(http.client.HTTPConnection, req) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = http_class = req = , http_conn_args = {} host = 'example.com', h = headers = {'Connection': 'close', 'Host': 'example.com', 'User-Agent': 'Python-urllib/3.13'} def do_open(self, http_class, req, **http_conn_args): """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. """ host = req.host if not host: raise URLError('no host given') # will parse host:port h = http_class(host, timeout=req.timeout, **http_conn_args) h.set_debuglevel(self._debuglevel) headers = dict(req.unredirected_hdrs) headers.update({k: v for k, v in req.headers.items() if k not in headers}) # TODO(jhylton): Should this be redesigned to handle # persistent connections? # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = {name.title(): val for name, val in headers.items()} if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: try: h.request(req.get_method(), req.selector, req.data, headers, encode_chunked=req.has_header('Transfer-encoding')) except OSError as err: # timeout error > raise URLError(err) E urllib.error.URLError: /usr/lib/python3.13/urllib/request.py:1322: URLError ______ test_headers_not_matching[Missing request header str expectation] _______ expected = {'Content-Type': 'application/pdf'}, requested = {} explanation = ["HeadersMatcher: Header 'Content-Type' not present"] @pytest.mark.parametrize( ("expected", "requested", "explanation"), ( pytest.param( {"Content-Type": "application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header str expectation", ), pytest.param( {"Content-Type": b"application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header bytes expectation", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, matching types", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, str expectation byte actual", ), pytest.param( {"Content-Type": b"application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, bytes expectation str actual", ), pytest.param( {"Content-Type": "re/json/"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: Regex didn't match: 'json' not found in " "'application/xml'" ) ], id="Non-matching values, re-format str expectation", ), ), ) def test_headers_not_matching(expected, requested, explanation): mock = pook.get("https://example.com") if expected: mock.headers(expected) request = pook.Request() request.url = "https://example.com" if requested: request.headers = requested matched, actual_explanation = mock.match(request) assert not matched > assert explanation == actual_explanation E assert ["HeadersMatc... not present"] == ['HeadersMatc...====.headers'] E E At index 0 diff: "HeadersMatcher: Header 'Content-Type' not present" != "HeadersMatcher: Header 'Content-Type' not present\nassert 'Content-Type' in HTTPHeaderDict({})\n + where HTTPHeaderDict({}) = ==================================================\\nMethod: GET\\nURL: https://example.com\\n==================================================.headers" E Use -v to get more diff tests/unit/matchers/headers_test.py:171: AssertionError _____ test_headers_not_matching[Missing request header bytes expectation] ______ expected = {'Content-Type': b'application/pdf'}, requested = {} explanation = ["HeadersMatcher: Header 'Content-Type' not present"] @pytest.mark.parametrize( ("expected", "requested", "explanation"), ( pytest.param( {"Content-Type": "application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header str expectation", ), pytest.param( {"Content-Type": b"application/pdf"}, {}, ["HeadersMatcher: Header 'Content-Type' not present"], id="Missing request header bytes expectation", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, matching types", ), pytest.param( {"Content-Type": "application/pdf"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, str expectation byte actual", ), pytest.param( {"Content-Type": b"application/pdf"}, {"Content-Type": "application/xml"}, [ ( "HeadersMatcher: 'application/pdf' != 'application/xml'\n" "- application/pdf\n" "? ^^^\n" "+ application/xml\n" "? ^^^\n" ) ], id="Non-matching values, bytes expectation str actual", ), pytest.param( {"Content-Type": "re/json/"}, {"Content-Type": b"application/xml"}, [ ( "HeadersMatcher: Regex didn't match: 'json' not found in " "'application/xml'" ) ], id="Non-matching values, re-format str expectation", ), ), ) def test_headers_not_matching(expected, requested, explanation): mock = pook.get("https://example.com") if expected: mock.headers(expected) request = pook.Request() request.url = "https://example.com" if requested: request.headers = requested matched, actual_explanation = mock.match(request) assert not matched > assert explanation == actual_explanation E assert ["HeadersMatc... not present"] == ['HeadersMatc...====.headers'] E E At index 0 diff: "HeadersMatcher: Header 'Content-Type' not present" != "HeadersMatcher: Header 'Content-Type' not present\nassert 'Content-Type' in HTTPHeaderDict({})\n + where HTTPHeaderDict({}) = ==================================================\\nMethod: GET\\nURL: https://example.com\\n==================================================.headers" E Use -v to get more diff tests/unit/matchers/headers_test.py:171: AssertionError ______________________ test_param_exists_empty_disallowed ______________________ URL = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook(allow_pending_mocks=True) def test_param_exists_empty_disallowed(URL): pook.get(URL).param_exists("x").reply(200) with pytest.raises(PookNoMatches): > urlopen(f"{URL}?x") tests/unit/matchers/query_test.py:19: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:495: in open response = meth(req, response) /usr/lib/python3.13/urllib/request.py:604: in http_response response = self.parent.error( /usr/lib/python3.13/urllib/request.py:533: in error return self._call_chain(*args) /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = fp = , code = 404 msg = 'NOT FOUND', hdrs = def http_error_default(self, req, fp, code, msg, hdrs): > raise HTTPError(req.full_url, code, msg, hdrs, fp) E urllib.error.HTTPError: HTTP Error 404: NOT FOUND /usr/lib/python3.13/urllib/request.py:613: HTTPError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404?x HTTP/1.1" 404 0 _______________________ test_param_exists_empty_allowed ________________________ URL = 'http://127.0.0.1:40727/status/404' @pytest.mark.pook def test_param_exists_empty_allowed(URL): pook.get(URL).param_exists("x", allow_empty=True).reply(200) > res = urlopen(f"{URL}?x") tests/unit/matchers/query_test.py:26: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:495: in open response = meth(req, response) /usr/lib/python3.13/urllib/request.py:604: in http_response response = self.parent.error( /usr/lib/python3.13/urllib/request.py:533: in error return self._call_chain(*args) /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = req = fp = , code = 404 msg = 'NOT FOUND', hdrs = def http_error_default(self, req, fp, code, msg, hdrs): > raise HTTPError(req.full_url, code, msg, hdrs, fp) E urllib.error.HTTPError: HTTP Error 404: NOT FOUND /usr/lib/python3.13/urllib/request.py:613: HTTPError ----------------------------- Captured stderr call ----------------------------- 127.0.0.1 - - [12/Feb/2026 23:17:50] "GET /status/404?x HTTP/1.1" 404 0 ________________________ test_mock_constructor[params] _________________________ param_kwargs = {'params': {'x': '1'}}, query_string = '?x=1' @pytest.mark.parametrize( ("param_kwargs", "query_string"), ( pytest.param({"params": {"x": "1"}}, "?x=1", id="params"), pytest.param( {"param": ("y", "pook")}, "?y=pook", marks=pytest.mark.xfail( condition=True, reason="Constructor does not correctly handle multi-argument methods from kwargs", ), id="param", ), pytest.param( {"param_exists": "z"}, "?z", marks=pytest.mark.xfail( condition=True, reason="Constructor does not have a method for passing `allow_empty` to `param_exists`", ), id="param_exists_empty_on_request", ), pytest.param( {"param_exists": "z"}, "?z=123", id="param_exists_has_value", ), ), ) def test_mock_constructor(param_kwargs, query_string): # Should not raise mock = Mock( url="https://httpbin.org/404", reply_status=200, response_json={"hello": "from pook"}, **param_kwargs, ) with pook.use(): pook.engine().add_mock(mock) > res = urlopen(f"https://httpbin.org/404{query_string}") tests/unit/mock_test.py:70: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:489: in open response = self._open(req, data) /usr/lib/python3.13/urllib/request.py:506: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) /usr/lib/python3.13/urllib/request.py:1367: in https_open return self.do_open(http.client.HTTPSConnection, req, /usr/lib/python3.13/urllib/request.py:1319: in do_open h.request(req.get_method(), req.selector, req.data, headers, pook/interceptors/http.py:110: in handler return self._on_request( pook/interceptors/http.py:61: in _on_request mock = self.engine.match(req) pook/engine.py:448: in match self.no_matches(msg) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = msg = "pook error!\n\n=> Cannot match any mock for the following request:\n=================================================...============\n\n=> Detailed matching errors:\nURLMatcher: 'httpbin.org' != '127.0.0.1'\n- httpbin.org\n+ 127.0.0.1\n\n" def no_matches(self, msg): """Raise `PookNoMatches` and reduce pytest printed stacktrace noise""" > raise PookNoMatches(msg) E pook.exceptions.PookNoMatches: pook error! E E => Cannot match any mock for the following request: E ================================================== E Method: GET E URL: https://127.0.0.1:9/404?x=1 E Query: {'x': ['1']} E Headers: HTTPHeaderDict({'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.13', 'Connection': 'close'}) E ================================================== E E => Detailed matching errors: E URLMatcher: 'httpbin.org' != '127.0.0.1' E - httpbin.org E + 127.0.0.1 pook/engine.py:455: PookNoMatches ________________ test_mock_constructor[param_exists_has_value] _________________ param_kwargs = {'param_exists': 'z'}, query_string = '?z=123' @pytest.mark.parametrize( ("param_kwargs", "query_string"), ( pytest.param({"params": {"x": "1"}}, "?x=1", id="params"), pytest.param( {"param": ("y", "pook")}, "?y=pook", marks=pytest.mark.xfail( condition=True, reason="Constructor does not correctly handle multi-argument methods from kwargs", ), id="param", ), pytest.param( {"param_exists": "z"}, "?z", marks=pytest.mark.xfail( condition=True, reason="Constructor does not have a method for passing `allow_empty` to `param_exists`", ), id="param_exists_empty_on_request", ), pytest.param( {"param_exists": "z"}, "?z=123", id="param_exists_has_value", ), ), ) def test_mock_constructor(param_kwargs, query_string): # Should not raise mock = Mock( url="https://httpbin.org/404", reply_status=200, response_json={"hello": "from pook"}, **param_kwargs, ) with pook.use(): pook.engine().add_mock(mock) > res = urlopen(f"https://httpbin.org/404{query_string}") tests/unit/mock_test.py:70: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /usr/lib/python3.13/urllib/request.py:189: in urlopen return opener.open(url, data, timeout) /usr/lib/python3.13/urllib/request.py:489: in open response = self._open(req, data) /usr/lib/python3.13/urllib/request.py:506: in _open result = self._call_chain(self.handle_open, protocol, protocol + /usr/lib/python3.13/urllib/request.py:466: in _call_chain result = func(*args) /usr/lib/python3.13/urllib/request.py:1367: in https_open return self.do_open(http.client.HTTPSConnection, req, /usr/lib/python3.13/urllib/request.py:1319: in do_open h.request(req.get_method(), req.selector, req.data, headers, pook/interceptors/http.py:110: in handler return self._on_request( pook/interceptors/http.py:61: in _on_request mock = self.engine.match(req) pook/engine.py:448: in match self.no_matches(msg) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = msg = "pook error!\n\n=> Cannot match any mock for the following request:\n=================================================...============\n\n=> Detailed matching errors:\nURLMatcher: 'httpbin.org' != '127.0.0.1'\n- httpbin.org\n+ 127.0.0.1\n\n" def no_matches(self, msg): """Raise `PookNoMatches` and reduce pytest printed stacktrace noise""" > raise PookNoMatches(msg) E pook.exceptions.PookNoMatches: pook error! E E => Cannot match any mock for the following request: E ================================================== E Method: GET E URL: https://127.0.0.1:9/404?z=123 E Query: {'z': ['123']} E Headers: HTTPHeaderDict({'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.13', 'Connection': 'close'}) E ================================================== E E => Detailed matching errors: E URLMatcher: 'httpbin.org' != '127.0.0.1' E - httpbin.org E + 127.0.0.1 pook/engine.py:455: PookNoMatches =============================== warnings summary =============================== ../../../../../../usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441 /usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441: PytestConfigWarning: Unknown config option: asyncio_default_fixture_loop_scope self._warn_or_fail_if_strict(f"Unknown config option: {key}\n") ../../../../../../usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441 /usr/lib/python3/dist-packages/_pytest/config/__init__.py:1441: PytestConfigWarning: Unknown config option: asyncio_mode self._warn_or_fail_if_strict(f"Unknown config option: {key}\n") tests/integration/pook_requests_test.py:6 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/integration/pook_requests_test.py:6: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html pytestmark = [pytest.mark.pook] tests/unit/interceptors/base.py:67 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:67: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:83 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:83: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/base.py:99 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:99: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/base.py:125 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:125: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/base.py:157 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:157: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:170 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:170: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:182 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:182: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:197 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:197: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:210 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:210: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:220 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:220: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:230 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:230: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/base.py:242 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/base.py:242: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/interceptors/aiohttp_test.py:8 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:8: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html pytestmark = [pytest.mark.pook] tests/unit/interceptors/aiohttp_test.py:32 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:32: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:42 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:42: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:52 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:52: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:60 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:60: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:69 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:69: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:79 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:79: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:91 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:91: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/aiohttp_test.py:105 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/aiohttp_test.py:105: PytestUnknownMarkWarning: Unknown pytest.mark.asyncio - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.asyncio tests/unit/interceptors/httpx_test.py:9 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/httpx_test.py:9: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html pytestmark = [pytest.mark.pook] tests/unit/interceptors/urllib3_test.py:107 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/urllib3_test.py:107: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/urllib_test.py:34 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/urllib_test.py:34: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/interceptors/urllib_test.py:42 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/interceptors/urllib_test.py:42: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/matchers/query_test.py:14 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/matchers/query_test.py:14: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/matchers/query_test.py:22 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/matchers/query_test.py:22: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/mock_engine_test.py:61 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/mock_engine_test.py:61: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook(allow_pending_mocks=True) tests/unit/mock_test.py:150 /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build/tests/unit/mock_test.py:150: PytestUnknownMarkWarning: Unknown pytest.mark.pook - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.pook tests/unit/api_test.py: 1 warning tests/unit/interceptors/aiohttp_test.py: 8 warnings tests/unit/interceptors/httpx_test.py: 1 warning /usr/lib/python3/dist-packages/_pytest/python.py:148: PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped. You need to install a suitable plugin for your async framework, for example: - anyio - pytest-asyncio - pytest-tornasync - pytest-trio - pytest-twisted warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid))) -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED tests/integration/examples_test.py::test_examples[aiohttp_client.py] FAILED tests/integration/examples_test.py::test_examples[decorators.py] - Ass... FAILED tests/integration/examples_test.py::test_examples[network_mode.py] - A... FAILED tests/integration/examples_test.py::test_examples[urllib3_client.py] FAILED tests/integration/examples_test.py::test_examples[network_mode_httpx.py] FAILED tests/integration/examples_test.py::test_examples[mock_context_manager.py] FAILED tests/integration/pook_requests_test.py::test_requests_get - requests.... FAILED tests/integration/pook_requests_test.py::test_requests_match_url - req... FAILED tests/integration/pook_requests_test.py::test_requests_match_query_params FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_activate_deactivate FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_network_mode FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_network_mode_hostname FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_multiple_network_filters FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_json_request FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_json_response FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_json_request_and_response FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_header_sent FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_mocked_response_headers FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_mutli_value_headers FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_mutli_value_response_headers FAILED tests/unit/interceptors/aiohttp_test.py::TestStandardAiohttp::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_activate_deactivate FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_network_mode FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_network_mode_hostname FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_multiple_network_filters FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_json_request FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_json_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_json_request_and_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_header_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_mocked_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_mutli_value_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_mutli_value_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardAsyncHttpx::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_activate_deactivate FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_network_mode FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_network_mode_hostname FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_multiple_network_filters FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_json_request FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_json_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_json_request_and_response FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_header_sent FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_mocked_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_mutli_value_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_mutli_value_response_headers FAILED tests/unit/interceptors/httpx_test.py::TestStandardSyncHttpx::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/httpx_test.py::test_sync - assert 404 == 200 FAILED tests/unit/interceptors/httpx_test.py::test_json - assert 404 == 200 FAILED tests/unit/interceptors/httpx_test.py::test_streaming[iter_bytes] - As... FAILED tests/unit/interceptors/httpx_test.py::test_streaming[iter_raw] - Asse... FAILED tests/unit/interceptors/httpx_test.py::test_redirect_following - asser... FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_activate_deactivate FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_network_mode FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_network_mode_hostname FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_multiple_network_filters FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_json_request FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_json_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_json_request_and_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_header_sent FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_mocked_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_mutli_value_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_mutli_value_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardUrllib3::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_activate_deactivate FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_network_mode FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_network_mode_hostname FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_multiple_network_filters FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_json_request FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_json_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_json_request_and_response FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_header_sent FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_mocked_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_mutli_value_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_mutli_value_response_headers FAILED tests/unit/interceptors/urllib3_test.py::TestStandardRequests::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/urllib3_test.py::test_post_with_headers - asse... FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_activate_deactivate FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_network_mode FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_network_mode_hostname FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_multiple_network_filters FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_json_request FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_json_response FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_json_request_and_response FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_header_sent FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_mocked_response_headers FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_mutli_value_headers FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_mutli_value_response_headers FAILED tests/unit/interceptors/urllib_test.py::TestUrllib::test_unmatched_headers_none_sent FAILED tests/unit/interceptors/urllib_test.py::test_urllib_ssl - urllib.error... FAILED tests/unit/interceptors/urllib_test.py::test_urllib_clear - urllib.err... FAILED tests/unit/matchers/headers_test.py::test_headers_not_matching[Missing request header str expectation] FAILED tests/unit/matchers/headers_test.py::test_headers_not_matching[Missing request header bytes expectation] FAILED tests/unit/matchers/query_test.py::test_param_exists_empty_disallowed FAILED tests/unit/matchers/query_test.py::test_param_exists_empty_allowed - u... FAILED tests/unit/mock_test.py::test_mock_constructor[params] - pook.exceptio... FAILED tests/unit/mock_test.py::test_mock_constructor[param_exists_has_value] ===== 95 failed, 124 passed, 10 skipped, 3 xfailed, 42 warnings in 21.41s ====== E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd /build/reproducible-path/python-pook-2.1.3/.pybuild/cpython3_3.13_pook/build; python3.13 -m pytest tests dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.12 3.13" returned exit code 13 make[1]: Leaving directory '/build/reproducible-path/python-pook-2.1.3' create-stamp debian/debhelper-build-stamp dh_testroot -O--buildsystem=pybuild dh_prep -O--buildsystem=pybuild dh_auto_install -O--buildsystem=pybuild I: pybuild plugin_pyproject:178: Copying package built for python3.12 to destdir I: pybuild plugin_pyproject:178: Copying package built for python3.13 to destdir dh_installdocs -O--buildsystem=pybuild dh_installdocs: warning: Cannot auto-detect main package for python-pook-doc. If the default is wrong, please use --doc-main-package dh_sphinxdoc -O--buildsystem=pybuild dh_installchangelogs -O--buildsystem=pybuild dh_installexamples -O--buildsystem=pybuild dh_python3 -O--buildsystem=pybuild dh_installsystemduser -O--buildsystem=pybuild dh_perl -O--buildsystem=pybuild dh_link -O--buildsystem=pybuild dh_strip_nondeterminism -O--buildsystem=pybuild dh_compress -O--buildsystem=pybuild dh_fixperms -O--buildsystem=pybuild dh_missing -O--buildsystem=pybuild dh_installdeb -O--buildsystem=pybuild dh_gencontrol -O--buildsystem=pybuild dpkg-gencontrol: warning: package python-pook-doc: substitution variable ${sphinxdoc:Built-Using} unused, but is defined dh_md5sums -O--buildsystem=pybuild dh_builddeb -O--buildsystem=pybuild dpkg-deb: building package 'python3-pook' in '../python3-pook_2.1.3-1_all.deb'. dpkg-deb: building package 'python-pook-doc' in '../python-pook-doc_2.1.3-1_all.deb'. dpkg-genbuildinfo --build=binary -O../python-pook_2.1.3-1_amd64.buildinfo dpkg-genchanges --build=binary -O../python-pook_2.1.3-1_amd64.changes dpkg-genchanges: info: binary-only upload (no source code included) dpkg-source --after-build . dpkg-source: info: using options from python-pook-2.1.3/debian/source/options: --extend-diff-ignore=^[^/]*[.]egg-info/ dpkg-buildpackage: info: binary-only upload (no source included) dpkg-genchanges: info: including full source code in upload I: copying local configuration I: user script /srv/workspace/pbuilder/263293/tmp/hooks/B01_cleanup starting I: user script /srv/workspace/pbuilder/263293/tmp/hooks/B01_cleanup finished I: unmounting dev/ptmx filesystem I: unmounting dev/pts filesystem I: unmounting dev/shm filesystem I: unmounting proc filesystem I: unmounting sys filesystem I: cleaning the build env I: removing directory /srv/workspace/pbuilder/263293 and its subdirectories I: Current time: Thu Feb 12 23:17:57 +14 2026 I: pbuilder-time-stamp: 1770887877