0s autopkgtest [14:45:19]: starting date and time: 2025-06-19 14:45:19+0000 0s autopkgtest [14:45:19]: git checkout: 9986aa8c Merge branch 'skia/fix_network_interface' into 'ubuntu/production' 0s autopkgtest [14:45:19]: host juju-7f2275-prod-proposed-migration-environment-2; command line: /home/ubuntu/autopkgtest/runner/autopkgtest --output-dir /tmp/autopkgtest-work.8246hbmh/out --timeout-copy=6000 --setup-commands /home/ubuntu/autopkgtest-cloud/worker-config-production/setup-canonical.sh --apt-pocket=proposed=src:requests --apt-upgrade python-mechanicalsoup --timeout-short=300 --timeout-copy=20000 --timeout-build=20000 --env=ADT_TEST_TRIGGERS=requests/2.32.3+dfsg-5ubuntu2 -- ssh -s /home/ubuntu/autopkgtest/ssh-setup/nova -- --flavor autopkgtest-cpu2-ram4-disk20-ppc64el --security-groups autopkgtest-juju-7f2275-prod-proposed-migration-environment-2@sto01-ppc64el-6.secgroup --name adt-questing-ppc64el-python-mechanicalsoup-20250619-144519-juju-7f2275-prod-proposed-migration-environment-2-e742e0b1-89bd-448b-ae78-44c026fd3e3f --image adt/ubuntu-questing-ppc64el-server --keyname testbed-juju-7f2275-prod-proposed-migration-environment-2 --net-id=net_prod-autopkgtest-workers-ppc64el -e TERM=linux --mirror=http://ftpmaster.internal/ubuntu/ 123s autopkgtest [14:47:22]: testbed dpkg architecture: ppc64el 123s autopkgtest [14:47:22]: testbed apt version: 3.1.2 123s autopkgtest [14:47:22]: @@@@@@@@@@@@@@@@@@@@ test bed setup 123s autopkgtest [14:47:22]: testbed release detected to be: None 124s autopkgtest [14:47:23]: updating testbed package index (apt update) 124s Get:1 http://ftpmaster.internal/ubuntu questing-proposed InRelease [249 kB] 124s Hit:2 http://ftpmaster.internal/ubuntu questing InRelease 124s Hit:3 http://ftpmaster.internal/ubuntu questing-updates InRelease 124s Hit:4 http://ftpmaster.internal/ubuntu questing-security InRelease 124s Get:5 http://ftpmaster.internal/ubuntu questing-proposed/universe Sources [426 kB] 124s Get:6 http://ftpmaster.internal/ubuntu questing-proposed/main Sources [38.3 kB] 125s Get:7 http://ftpmaster.internal/ubuntu questing-proposed/restricted Sources [4716 B] 125s Get:8 http://ftpmaster.internal/ubuntu questing-proposed/multiverse Sources [17.4 kB] 125s Get:9 http://ftpmaster.internal/ubuntu questing-proposed/main ppc64el Packages [66.7 kB] 125s Get:10 http://ftpmaster.internal/ubuntu questing-proposed/restricted ppc64el Packages [724 B] 125s Get:11 http://ftpmaster.internal/ubuntu questing-proposed/universe ppc64el Packages [340 kB] 125s Get:12 http://ftpmaster.internal/ubuntu questing-proposed/multiverse ppc64el Packages [6448 B] 125s Fetched 1149 kB in 0s (2432 kB/s) 126s Reading package lists... 126s autopkgtest [14:47:25]: upgrading testbed (apt dist-upgrade and autopurge) 126s Reading package lists... 126s Building dependency tree... 126s Reading state information... 126s Calculating upgrade... 127s The following packages will be upgraded: 127s python3-requests 127s 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 127s Need to get 53.1 kB of archives. 127s After this operation, 0 B of additional disk space will be used. 127s Get:1 http://ftpmaster.internal/ubuntu questing-proposed/main ppc64el python3-requests all 2.32.3+dfsg-5ubuntu2 [53.1 kB] 127s Fetched 53.1 kB in 0s (2564 kB/s) 128s (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 ... 79652 files and directories currently installed.) 128s Preparing to unpack .../python3-requests_2.32.3+dfsg-5ubuntu2_all.deb ... 128s Unpacking python3-requests (2.32.3+dfsg-5ubuntu2) over (2.32.3+dfsg-5ubuntu1) ... 128s Setting up python3-requests (2.32.3+dfsg-5ubuntu2) ... 128s Reading package lists... 128s Building dependency tree... 128s Reading state information... 128s Solving dependencies... 128s 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. 131s autopkgtest [14:47:30]: testbed running kernel: Linux 6.14.0-15-generic #15-Ubuntu SMP Sun Apr 6 14:52:42 UTC 2025 131s autopkgtest [14:47:30]: @@@@@@@@@@@@@@@@@@@@ apt-source python-mechanicalsoup 132s Get:1 http://ftpmaster.internal/ubuntu questing/universe python-mechanicalsoup 1.4.0-0ubuntu2 (dsc) [2371 B] 132s Get:2 http://ftpmaster.internal/ubuntu questing/universe python-mechanicalsoup 1.4.0-0ubuntu2 (tar) [152 kB] 132s Get:3 http://ftpmaster.internal/ubuntu questing/universe python-mechanicalsoup 1.4.0-0ubuntu2 (diff) [4136 B] 132s gpgv: Signature made Mon Jun 2 09:47:37 2025 UTC 132s gpgv: using RSA key 568BF22A66337CBFC9A6B9B72C83DBC8E9BD0E37 132s gpgv: Can't check signature: No public key 132s dpkg-source: warning: cannot verify inline signature for ./python-mechanicalsoup_1.4.0-0ubuntu2.dsc: no acceptable signature found 132s autopkgtest [14:47:31]: testing package python-mechanicalsoup version 1.4.0-0ubuntu2 133s autopkgtest [14:47:32]: build not needed 133s autopkgtest [14:47:32]: test command1: preparing testbed 133s Reading package lists... 134s Building dependency tree... 134s Reading state information... 134s Solving dependencies... 134s The following NEW packages will be installed: 134s libjs-jquery libxslt1.1 python3-all python3-brotli python3-brotlicffi 134s python3-bs4 python3-click python3-decorator python3-flasgger python3-flask 134s python3-greenlet python3-httpbin python3-iniconfig python3-itsdangerous 134s python3-lxml python3-mechanicalsoup python3-mistune python3-pluggy 134s python3-pytest python3-pytest-httpbin python3-pytest-mock 134s python3-requests-mock python3-soupsieve python3-werkzeug 134s 0 upgraded, 24 newly installed, 0 to remove and 0 not upgraded. 134s Need to get 5258 kB of archives. 134s After this operation, 25.5 MB of additional disk space will be used. 134s Get:1 http://ftpmaster.internal/ubuntu questing/main ppc64el libjs-jquery all 3.6.1+dfsg+~3.5.14-1 [328 kB] 134s Get:2 http://ftpmaster.internal/ubuntu questing/main ppc64el libxslt1.1 ppc64el 1.1.43-0exp1 [184 kB] 134s Get:3 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-all ppc64el 3.13.4-1 [880 B] 134s Get:4 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-brotli ppc64el 1.1.0-2build4 [422 kB] 134s Get:5 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-brotlicffi ppc64el 1.1.0.0+ds1-1 [19.0 kB] 134s Get:6 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-soupsieve all 2.7-1 [33.5 kB] 134s Get:7 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-bs4 all 4.13.4-3 [137 kB] 134s Get:8 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-click all 8.2.0+0.really.8.1.8-1 [80.0 kB] 134s Get:9 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-decorator all 5.2.1-2 [28.1 kB] 134s Get:10 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-itsdangerous all 2.2.0-2 [15.3 kB] 134s Get:11 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-werkzeug all 3.1.3-2 [169 kB] 134s Get:12 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-flask all 3.1.1-1ubuntu1 [84.6 kB] 134s Get:13 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-mistune all 3.1.3-1 [35.0 kB] 134s Get:14 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-flasgger all 0.9.7.2~dev2+dfsg-4 [1692 kB] 135s Get:15 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-greenlet ppc64el 3.1.0-1build1 [168 kB] 135s Get:16 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-httpbin all 0.10.2+dfsg-2 [89.0 kB] 135s Get:17 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-iniconfig all 1.1.1-2 [6024 B] 135s Get:18 http://ftpmaster.internal/ubuntu questing/main ppc64el python3-lxml ppc64el 5.4.0-1build1 [1432 kB] 135s Get:19 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-mechanicalsoup all 1.4.0-0ubuntu2 [18.6 kB] 135s Get:20 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-pluggy all 1.5.0-1 [21.0 kB] 135s Get:21 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-pytest all 8.3.5-2 [252 kB] 135s Get:22 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-pytest-httpbin all 2.1.0-1 [13.0 kB] 135s Get:23 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-pytest-mock all 3.14.0-2 [11.7 kB] 135s Get:24 http://ftpmaster.internal/ubuntu questing/universe ppc64el python3-requests-mock all 1.12.1-3 [17.8 kB] 135s Fetched 5258 kB in 2s (3414 kB/s) 135s Selecting previously unselected package libjs-jquery. 135s (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 ... 79652 files and directories currently installed.) 135s Preparing to unpack .../00-libjs-jquery_3.6.1+dfsg+~3.5.14-1_all.deb ... 135s Unpacking libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... 136s Selecting previously unselected package libxslt1.1:ppc64el. 136s Preparing to unpack .../01-libxslt1.1_1.1.43-0exp1_ppc64el.deb ... 136s Unpacking libxslt1.1:ppc64el (1.1.43-0exp1) ... 136s Selecting previously unselected package python3-all. 136s Preparing to unpack .../02-python3-all_3.13.4-1_ppc64el.deb ... 136s Unpacking python3-all (3.13.4-1) ... 136s Selecting previously unselected package python3-brotli. 136s Preparing to unpack .../03-python3-brotli_1.1.0-2build4_ppc64el.deb ... 136s Unpacking python3-brotli (1.1.0-2build4) ... 136s Selecting previously unselected package python3-brotlicffi. 136s Preparing to unpack .../04-python3-brotlicffi_1.1.0.0+ds1-1_ppc64el.deb ... 136s Unpacking python3-brotlicffi (1.1.0.0+ds1-1) ... 136s Selecting previously unselected package python3-soupsieve. 136s Preparing to unpack .../05-python3-soupsieve_2.7-1_all.deb ... 136s Unpacking python3-soupsieve (2.7-1) ... 136s Selecting previously unselected package python3-bs4. 136s Preparing to unpack .../06-python3-bs4_4.13.4-3_all.deb ... 136s Unpacking python3-bs4 (4.13.4-3) ... 136s Selecting previously unselected package python3-click. 136s Preparing to unpack .../07-python3-click_8.2.0+0.really.8.1.8-1_all.deb ... 136s Unpacking python3-click (8.2.0+0.really.8.1.8-1) ... 136s Selecting previously unselected package python3-decorator. 136s Preparing to unpack .../08-python3-decorator_5.2.1-2_all.deb ... 136s Unpacking python3-decorator (5.2.1-2) ... 136s Selecting previously unselected package python3-itsdangerous. 136s Preparing to unpack .../09-python3-itsdangerous_2.2.0-2_all.deb ... 136s Unpacking python3-itsdangerous (2.2.0-2) ... 136s Selecting previously unselected package python3-werkzeug. 136s Preparing to unpack .../10-python3-werkzeug_3.1.3-2_all.deb ... 136s Unpacking python3-werkzeug (3.1.3-2) ... 136s Selecting previously unselected package python3-flask. 136s Preparing to unpack .../11-python3-flask_3.1.1-1ubuntu1_all.deb ... 136s Unpacking python3-flask (3.1.1-1ubuntu1) ... 136s Selecting previously unselected package python3-mistune. 136s Preparing to unpack .../12-python3-mistune_3.1.3-1_all.deb ... 136s Unpacking python3-mistune (3.1.3-1) ... 136s Selecting previously unselected package python3-flasgger. 136s Preparing to unpack .../13-python3-flasgger_0.9.7.2~dev2+dfsg-4_all.deb ... 136s Unpacking python3-flasgger (0.9.7.2~dev2+dfsg-4) ... 136s Selecting previously unselected package python3-greenlet. 136s Preparing to unpack .../14-python3-greenlet_3.1.0-1build1_ppc64el.deb ... 136s Unpacking python3-greenlet (3.1.0-1build1) ... 136s Selecting previously unselected package python3-httpbin. 136s Preparing to unpack .../15-python3-httpbin_0.10.2+dfsg-2_all.deb ... 136s Unpacking python3-httpbin (0.10.2+dfsg-2) ... 136s Selecting previously unselected package python3-iniconfig. 136s Preparing to unpack .../16-python3-iniconfig_1.1.1-2_all.deb ... 136s Unpacking python3-iniconfig (1.1.1-2) ... 136s Selecting previously unselected package python3-lxml:ppc64el. 136s Preparing to unpack .../17-python3-lxml_5.4.0-1build1_ppc64el.deb ... 136s Unpacking python3-lxml:ppc64el (5.4.0-1build1) ... 136s Selecting previously unselected package python3-mechanicalsoup. 136s Preparing to unpack .../18-python3-mechanicalsoup_1.4.0-0ubuntu2_all.deb ... 136s Unpacking python3-mechanicalsoup (1.4.0-0ubuntu2) ... 136s Selecting previously unselected package python3-pluggy. 136s Preparing to unpack .../19-python3-pluggy_1.5.0-1_all.deb ... 136s Unpacking python3-pluggy (1.5.0-1) ... 136s Selecting previously unselected package python3-pytest. 136s Preparing to unpack .../20-python3-pytest_8.3.5-2_all.deb ... 136s Unpacking python3-pytest (8.3.5-2) ... 136s Selecting previously unselected package python3-pytest-httpbin. 136s Preparing to unpack .../21-python3-pytest-httpbin_2.1.0-1_all.deb ... 136s Unpacking python3-pytest-httpbin (2.1.0-1) ... 136s Selecting previously unselected package python3-pytest-mock. 136s Preparing to unpack .../22-python3-pytest-mock_3.14.0-2_all.deb ... 136s Unpacking python3-pytest-mock (3.14.0-2) ... 136s Selecting previously unselected package python3-requests-mock. 136s Preparing to unpack .../23-python3-requests-mock_1.12.1-3_all.deb ... 136s Unpacking python3-requests-mock (1.12.1-3) ... 136s Setting up python3-iniconfig (1.1.1-2) ... 136s Setting up python3-brotlicffi (1.1.0.0+ds1-1) ... 136s Setting up python3-itsdangerous (2.2.0-2) ... 136s Setting up python3-all (3.13.4-1) ... 136s Setting up python3-click (8.2.0+0.really.8.1.8-1) ... 136s Setting up python3-decorator (5.2.1-2) ... 137s Setting up python3-werkzeug (3.1.3-2) ... 137s Setting up python3-brotli (1.1.0-2build4) ... 137s Setting up python3-requests-mock (1.12.1-3) ... 137s Setting up python3-greenlet (3.1.0-1build1) ... 137s Setting up python3-pluggy (1.5.0-1) ... 137s Setting up libxslt1.1:ppc64el (1.1.43-0exp1) ... 137s Setting up libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... 137s Setting up python3-mistune (3.1.3-1) ... 137s Setting up python3-soupsieve (2.7-1) ... 137s Setting up python3-pytest (8.3.5-2) ... 138s Setting up python3-flask (3.1.1-1ubuntu1) ... 138s Setting up python3-bs4 (4.13.4-3) ... 138s Setting up python3-pytest-mock (3.14.0-2) ... 138s Setting up python3-lxml:ppc64el (5.4.0-1build1) ... 138s Setting up python3-flasgger (0.9.7.2~dev2+dfsg-4) ... 138s Setting up python3-mechanicalsoup (1.4.0-0ubuntu2) ... 139s Setting up python3-httpbin (0.10.2+dfsg-2) ... 139s Setting up python3-pytest-httpbin (2.1.0-1) ... 139s Processing triggers for man-db (2.13.1-1) ... 139s Processing triggers for libc-bin (2.41-6ubuntu2) ... 140s autopkgtest [14:47:39]: test command1: set -e ; cp -r tests "$AUTOPKGTEST_TMP" ; for py in $(py3versions -r 2>/dev/null) ; do cd "$AUTOPKGTEST_TMP" ; echo "Testing with $py:" ; $py -m pytest -v -k 'not submit_online and not get_request_kwargs and not submit_set and not new_control' ; done 140s autopkgtest [14:47:39]: test command1: [----------------------- 140s ************************************************************************** 140s # A new feature in cloud-init identified possible datasources for # 140s # this system as: # 140s # [] # 140s # However, the datasource used was: OpenStack # 140s # # 140s # In the future, cloud-init will only attempt to use datasources that # 140s # are identified or specifically configured. # 140s # For more information see # 140s # https://bugs.launchpad.net/bugs/1669675 # 140s # # 140s # If you are seeing this message, please file a bug against # 140s # cloud-init at # 140s # https://github.com/canonical/cloud-init/issues # 140s # Make sure to include the cloud provider your instance is # 140s # running on. # 140s # # 140s # After you have filed a bug, you can disable this warning by launching # 140s # your instance with the cloud-config below, or putting that content # 140s # into /etc/cloud/cloud.cfg.d/99-warnings.cfg # 140s # # 140s # #cloud-config # 140s # warnings: # 140s # dsid_missing_source: off # 140s ************************************************************************** 140s 140s Disable the warnings above by: 140s touch /home/ubuntu/.cloud-warnings.skip 140s or 140s touch /var/lib/cloud/instance/warnings/.skip 141s Testing with python3.13: 141s ============================= test session starts ============================== 141s platform linux -- Python 3.13.5, pytest-8.3.5, pluggy-1.5.0 -- /usr/bin/python3.13 141s cachedir: .pytest_cache 141s rootdir: /tmp/autopkgtest.SNrEvJ/autopkgtest_tmp 141s plugins: typeguard-4.4.2, requests_mock-1.12.1, mock-3.14.0, httpbin-2.1.0 141s collecting ... collected 121 items / 8 deselected / 113 selected 141s 141s tests/test_browser.py::test__request FAILED [ 0%] 141s tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-True-] FAILED [ 1%] 142s tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-True-] FAILED [ 2%] 142s tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-False-] FAILED [ 3%] 142s tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-False-] FAILED [ 4%] 142s tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-True-] FAILED [ 5%] 142s tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-True-] FAILED [ 6%] 142s tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-False-] FAILED [ 7%] 142s tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-False-] FAILED [ 7%] 142s tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-True-] FAILED [ 8%] 142s tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-True-] FAILED [ 9%] 142s tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-False-] FAILED [ 10%] 142s tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-False-] FAILED [ 11%] 142s tests/test_browser.py::test__request_select_none FAILED [ 12%] 142s tests/test_browser.py::test__request_disabled_attr FAILED [ 13%] 142s tests/test_browser.py::test_request_keyword_error[method] PASSED [ 14%] 142s tests/test_browser.py::test_request_keyword_error[url] PASSED [ 15%] 142s tests/test_browser.py::test_no_404 FAILED [ 15%] 142s tests/test_browser.py::test_404 FAILED [ 16%] 142s tests/test_browser.py::test_set_cookiejar FAILED [ 17%] 142s tests/test_browser.py::test_get_cookiejar FAILED [ 18%] 142s tests/test_browser.py::test_post FAILED [ 19%] 142s tests/test_browser.py::test_put FAILED [ 20%] 142s tests/test_browser.py::test_encoding[http_html_expected_encoding0] PASSED [ 21%] 142s tests/test_browser.py::test_encoding[http_html_expected_encoding1] PASSED [ 22%] 142s tests/test_browser.py::test_encoding[http_html_expected_encoding2] PASSED [ 23%] 142s tests/test_browser.py::test_encoding[http_html_expected_encoding3] PASSED [ 23%] 142s tests/test_form.py::test_construct_form_fail PASSED [ 24%] 142s tests/test_form.py::test_choose_submit[preview] PASSED [ 25%] 142s tests/test_form.py::test_choose_submit[save] PASSED [ 26%] 142s tests/test_form.py::test_choose_submit[cancel] PASSED [ 27%] 142s tests/test_form.py::test_choose_submit_from_selector[first] PASSED [ 28%] 142s tests/test_form.py::test_choose_submit_from_selector[second] PASSED [ 29%] 142s tests/test_form.py::test_choose_submit_fail[not found] PASSED [ 30%] 142s tests/test_form.py::test_choose_submit_fail[found] PASSED [ 30%] 142s tests/test_form.py::test_choose_submit_twice PASSED [ 31%] 142s tests/test_form.py::test_choose_submit_multiple_match PASSED [ 32%] 142s tests/test_form.py::test_form_noaction PASSED [ 33%] 142s tests/test_form.py::test_form_action PASSED [ 34%] 142s tests/test_form.py::test_set_select[default] PASSED [ 35%] 142s tests/test_form.py::test_set_select[selected] PASSED [ 36%] 142s tests/test_form.py::test_set_select_multiple[select one (str)] PASSED [ 37%] 142s tests/test_form.py::test_set_select_multiple[select one (tuple)] PASSED [ 38%] 142s tests/test_form.py::test_set_select_multiple[select two] PASSED [ 38%] 142s tests/test_form.py::test_form_not_found PASSED [ 39%] 142s tests/test_form.py::test_form_set_radio_checkbox PASSED [ 40%] 142s tests/test_form.py::test_form_check_uncheck PASSED [ 41%] 142s tests/test_form.py::test_form_print_summary PASSED [ 42%] 142s tests/test_form.py::test_issue180 PASSED [ 43%] 142s tests/test_form.py::test_issue158 PASSED [ 44%] 142s tests/test_form.py::test_duplicate_submit_buttons PASSED [ 45%] 142s tests/test_form.py::test_choose_submit_buttons[submit button] PASSED [ 46%] 142s tests/test_form.py::test_choose_submit_buttons[typeless button] PASSED [ 46%] 142s tests/test_form.py::test_choose_submit_buttons[submit input] PASSED [ 47%] 142s tests/test_form.py::test_option_without_value[Option with value] PASSED [ 48%] 142s tests/test_form.py::test_option_without_value[Option without value] PASSED [ 49%] 142s tests/test_form.py::test_option_without_value[Option with value selected by its text] PASSED [ 50%] 142s tests/test_form.py::test_option_without_value[Unknown option, must raise a LinkNotFound exception] PASSED [ 51%] 142s tests/test_stateful_browser.py::test_request_forward PASSED [ 52%] 142s tests/test_stateful_browser.py::test_properties PASSED [ 53%] 142s tests/test_stateful_browser.py::test_get_selected_form_unselected PASSED [ 53%] 142s tests/test_stateful_browser.py::test_no_404 FAILED [ 54%] 142s tests/test_stateful_browser.py::test_404 FAILED [ 55%] 142s tests/test_stateful_browser.py::test_user_agent FAILED [ 56%] 142s tests/test_stateful_browser.py::test_open_relative FAILED [ 57%] 142s tests/test_stateful_browser.py::test_links PASSED [ 58%] 142s tests/test_stateful_browser.py::test_submit_btnName[input] PASSED [ 59%] 142s tests/test_stateful_browser.py::test_submit_btnName[button] PASSED [ 60%] 142s tests/test_stateful_browser.py::test_submit_no_btn[input] PASSED [ 61%] 142s tests/test_stateful_browser.py::test_submit_no_btn[button] PASSED [ 61%] 142s tests/test_stateful_browser.py::test_submit_dont_modify_kwargs PASSED [ 62%] 142s tests/test_stateful_browser.py::test_submit_dont_update_state PASSED [ 63%] 142s tests/test_stateful_browser.py::test_get_set_debug PASSED [ 64%] 142s tests/test_stateful_browser.py::test_list_links PASSED [ 65%] 142s tests/test_stateful_browser.py::test_launch_browser PASSED [ 66%] 142s tests/test_stateful_browser.py::test_find_link PASSED [ 67%] 142s tests/test_stateful_browser.py::test_verbose PASSED [ 68%] 142s tests/test_stateful_browser.py::test_form_noaction PASSED [ 69%] 142s tests/test_stateful_browser.py::test_form_noname PASSED [ 69%] 142s tests/test_stateful_browser.py::test_form_multiple PASSED [ 70%] 142s tests/test_stateful_browser.py::test_upload_file FAILED [ 71%] 143s tests/test_stateful_browser.py::test_upload_file_with_malicious_default FAILED [ 72%] 143s tests/test_stateful_browser.py::test_upload_file_raise_on_string_input PASSED [ 73%] 143s tests/test_stateful_browser.py::test_with PASSED [ 74%] 143s tests/test_stateful_browser.py::test_select_form_nr PASSED [ 75%] 143s tests/test_stateful_browser.py::test_select_form_tag_object PASSED [ 76%] 143s tests/test_stateful_browser.py::test_select_form_associated_elements XFAIL [ 76%] 143s tests/test_stateful_browser.py::test_referer_follow_link FAILED [ 77%] 143s tests/test_stateful_browser.py::test_referer_submit FAILED [ 78%] 143s tests/test_stateful_browser.py::test_referer_submit_override[Referer] FAILED [ 79%] 143s tests/test_stateful_browser.py::test_referer_submit_override[referer] FAILED [ 80%] 143s tests/test_stateful_browser.py::test_referer_submit_headers FAILED [ 81%] 143s tests/test_stateful_browser.py::test_follow_link_arg[none] PASSED [ 82%] 143s tests/test_stateful_browser.py::test_follow_link_arg[string] PASSED [ 83%] 143s tests/test_stateful_browser.py::test_follow_link_arg[regex] PASSED [ 84%] 143s tests/test_stateful_browser.py::test_follow_link_from_tag PASSED [ 84%] 143s tests/test_stateful_browser.py::test_follow_link_excess PASSED [ 85%] 143s tests/test_stateful_browser.py::test_follow_link_ua FAILED [ 86%] 143s tests/test_stateful_browser.py::test_link_arg_multiregex PASSED [ 87%] 143s tests/test_stateful_browser.py::test_download_link FAILED [ 88%] 143s tests/test_stateful_browser.py::test_download_link_nofile FAILED [ 89%] 143s tests/test_stateful_browser.py::test_download_link_nofile_bs4 FAILED [ 90%] 143s tests/test_stateful_browser.py::test_download_link_nofile_excess FAILED [ 91%] 143s tests/test_stateful_browser.py::test_download_link_nofile_ua FAILED [ 92%] 143s tests/test_stateful_browser.py::test_download_link_to_existing_file FAILED [ 92%] 143s tests/test_stateful_browser.py::test_download_link_404 FAILED [ 93%] 143s tests/test_stateful_browser.py::test_download_link_referer FAILED [ 94%] 143s tests/test_stateful_browser.py::test_refresh_open PASSED [ 95%] 143s tests/test_stateful_browser.py::test_refresh_follow_link PASSED [ 96%] 143s tests/test_stateful_browser.py::test_refresh_form_not_retained PASSED [ 97%] 143s tests/test_stateful_browser.py::test_refresh_error PASSED [ 98%] 143s tests/test_stateful_browser.py::test_requests_session_and_cookies FAILED [ 99%] 143s tests/test_utils.py::test_LinkNotFoundError PASSED [100%] 143s 143s =================================== FAILURES =================================== 143s ________________________________ test__request _________________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test__request(httpbin): 143s form_html = f""" 143s
143s 143s 143s 143s
143s Pizza Size 143s

Small

143s

Medium

143s

Large

143s
143s
143s Pizza Toppings 143s

Bacon

143s

Extra Cheese

143s

Onion

143s

Mushroom

143s
143s 143s
143s """ 143s 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s > data = response.json()['form'] 143s 143s tests/test_browser.py:109: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _ test_enctype_and_file_submit[multipart/form-data-True-] _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'multipart/form-data', submit_file = True 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ___________ test_enctype_and_file_submit[multipart/form-data-True-] ____________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'multipart/form-data', submit_file = True, file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _ test_enctype_and_file_submit[multipart/form-data-False-] _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'multipart/form-data', submit_file = False 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ___________ test_enctype_and_file_submit[multipart/form-data-False-] ___________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'multipart/form-data', submit_file = False, file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _ test_enctype_and_file_submit[application/x-www-form-urlencoded-True-] _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'application/x-www-form-urlencoded', submit_file = True 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ____ test_enctype_and_file_submit[application/x-www-form-urlencoded-True-] _____ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'application/x-www-form-urlencoded', submit_file = True 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _ test_enctype_and_file_submit[application/x-www-form-urlencoded-False-] _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'application/x-www-form-urlencoded', submit_file = False 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ____ test_enctype_and_file_submit[application/x-www-form-urlencoded-False-] ____ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'application/x-www-form-urlencoded', submit_file = False 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _ test_enctype_and_file_submit[Invalid enctype-True-] _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'Invalid enctype', submit_file = True 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _____________ test_enctype_and_file_submit[Invalid enctype-True-] ______________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'Invalid enctype', submit_file = True, file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _ test_enctype_and_file_submit[Invalid enctype-False-] _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'Invalid enctype', submit_file = False 143s file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _____________ test_enctype_and_file_submit[Invalid enctype-False-] _____________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s enctype = 'Invalid enctype', submit_file = False, file_field = '' 143s 143s @pytest.mark.parametrize("file_field", [ 143s """""", 143s ""]) 143s @pytest.mark.parametrize("submit_file", [ 143s True, 143s False 143s ]) 143s @pytest.mark.parametrize("enctype", [ 143s pytest.param("multipart/form-data"), 143s pytest.param("application/x-www-form-urlencoded"), 143s pytest.param("Invalid enctype") 143s ]) 143s def test_enctype_and_file_submit(httpbin, enctype, submit_file, file_field): 143s # test if enctype is respected when specified 143s # and if files are processed correctly 143s form_html = f""" 143s
143s 143s {file_field} 143s
143s """ 143s form = BeautifulSoup(form_html, "lxml").form 143s 143s valid_enctype = (enctype in valid_enctypes_file_submit and 143s valid_enctypes_file_submit[enctype]) 143s expected_content = b"" # default 143s if submit_file and file_field: 143s # create a temporary file for testing file upload 143s file_content = b":-)" 143s pic_filedescriptor, pic_path = tempfile.mkstemp() 143s pic_filename = os.path.basename(pic_path) 143s os.write(pic_filedescriptor, file_content) 143s os.close(pic_filedescriptor) 143s if valid_enctype: 143s # Correct encoding => send the content 143s expected_content = file_content 143s else: 143s # Encoding doesn't allow sending the content, we expect 143s # the filename as a normal text field. 143s expected_content = os.path.basename(pic_path.encode()) 143s tag = form.find("input", {"name": "pic"}) 143s tag["value"] = open(pic_path, "rb") 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s 143s if enctype not in valid_enctypes_file_submit: 143s expected_enctype = default_enctype 143s else: 143s expected_enctype = enctype 143s assert expected_enctype in response.request.headers["Content-Type"] 143s 143s > resp = response.json() 143s 143s tests/test_browser.py:180: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s __________________________ test__request_select_none ___________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test__request_select_none(httpbin): 143s """Make sure that a 143s 143s 143s 143s """ 143s 143s form = BeautifulSoup(form_html, "lxml").form 143s browser = mechanicalsoup.Browser() 143s response = browser._request(form) 143s > assert response.json()['form'] == {'shape': 'round'} 143s 143s tests/test_browser.py:229: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _________________________ test__request_disabled_attr __________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test__request_disabled_attr(httpbin): 143s """Make sure that disabled form controls are not submitted.""" 143s form_html = f""" 143s
143s 143s
""" 143s 143s browser = mechanicalsoup.Browser() 143s response = browser._request(BeautifulSoup(form_html, "lxml").form) 143s > assert response.json()['form'] == {} 143s 143s tests/test_browser.py:241: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _________________________________ test_no_404 __________________________________ 143s 143s httpbin = 143s 143s def test_no_404(httpbin): 143s browser = mechanicalsoup.Browser() 143s resp = browser.get(httpbin + "/nosuchpage") 143s > assert resp.status_code == 404 143s E assert 503 == 404 143s E + where 503 = .status_code 143s 143s tests/test_browser.py:260: AssertionError 143s ___________________________________ test_404 ___________________________________ 143s 143s httpbin = 143s 143s def test_404(httpbin): 143s browser = mechanicalsoup.Browser(raise_on_404=True) 143s > with pytest.raises(mechanicalsoup.LinkNotFoundError): 143s E Failed: DID NOT RAISE 143s 143s tests/test_browser.py:265: Failed 143s ______________________________ test_set_cookiejar ______________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_set_cookiejar(httpbin): 143s """Set cookies locally and test that they are received remotely.""" 143s # construct a phony cookiejar and attach it to the session 143s jar = RequestsCookieJar() 143s jar.set('field', 'value') 143s assert jar.get('field') == 'value' 143s 143s browser = mechanicalsoup.Browser() 143s browser.set_cookiejar(jar) 143s resp = browser.get(httpbin + "/cookies") 143s > assert resp.json() == {'cookies': {'field': 'value'}} 143s 143s tests/test_browser.py:281: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ______________________________ test_get_cookiejar ______________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_get_cookiejar(httpbin): 143s """Test that cookies set by the remote host update our session.""" 143s browser = mechanicalsoup.Browser() 143s resp = browser.get(httpbin + "/cookies/set?k1=v1&k2=v2") 143s > assert resp.json() == {'cookies': {'k1': 'v1', 'k2': 'v2'}} 143s 143s tests/test_browser.py:288: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s __________________________________ test_post ___________________________________ 143s 143s httpbin = 143s 143s def test_post(httpbin): 143s browser = mechanicalsoup.Browser() 143s data = {'color': 'blue', 'colorblind': 'True'} 143s resp = browser.post(httpbin + "/post", data) 143s > assert resp.status_code == 200 and resp.json()['form'] == data 143s E assert (503 == 200) 143s E + where 503 = .status_code 143s 143s tests/test_browser.py:299: AssertionError 143s ___________________________________ test_put ___________________________________ 143s 143s httpbin = 143s 143s def test_put(httpbin): 143s browser = mechanicalsoup.Browser() 143s data = {'color': 'blue', 'colorblind': 'True'} 143s resp = browser.put(httpbin + "/put", data) 143s > assert resp.status_code == 200 and resp.json()['form'] == data 143s E assert (503 == 200) 143s E + where 503 = .status_code 143s 143s tests/test_browser.py:306: AssertionError 143s _________________________________ test_no_404 __________________________________ 143s 143s httpbin = 143s 143s def test_no_404(httpbin): 143s browser = mechanicalsoup.StatefulBrowser() 143s resp = browser.open(httpbin + "/nosuchpage") 143s > assert resp.status_code == 404 143s E assert 503 == 404 143s E + where 503 = .status_code 143s 143s tests/test_stateful_browser.py:86: AssertionError 143s ___________________________________ test_404 ___________________________________ 143s 143s httpbin = 143s 143s def test_404(httpbin): 143s browser = mechanicalsoup.StatefulBrowser(raise_on_404=True) 143s > with pytest.raises(mechanicalsoup.LinkNotFoundError): 143s E Failed: DID NOT RAISE 143s 143s tests/test_stateful_browser.py:91: Failed 143s _______________________________ test_user_agent ________________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_user_agent(httpbin): 143s browser = mechanicalsoup.StatefulBrowser(user_agent='007') 143s resp = browser.open(httpbin + "/user-agent") 143s > assert resp.json() == {'user-agent': '007'} 143s 143s tests/test_stateful_browser.py:100: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ______________________________ test_open_relative ______________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_open_relative(httpbin): 143s # Open an arbitrary httpbin page to set the current URL 143s browser = mechanicalsoup.StatefulBrowser() 143s browser.open(httpbin + "/html") 143s 143s # Open a relative page and make sure remote host and browser agree on URL 143s resp = browser.open_relative("/get") 143s > assert resp.json()['url'] == httpbin + "/get" 143s 143s tests/test_stateful_browser.py:110: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s _______________________________ test_upload_file _______________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_upload_file(httpbin): 143s browser = mechanicalsoup.StatefulBrowser() 143s url = httpbin + "/post" 143s file_input_form = f""" 143s
143s 143s
143s """ 143s 143s # Create two temporary files to upload 143s def make_file(content): 143s path = tempfile.mkstemp()[1] 143s with open(path, "w") as fd: 143s fd.write(content) 143s return path 143s path1 = make_file("first file content") 143s path2 = make_file("second file content") 143s 143s value1 = open(path1, "rb") 143s value2 = open(path2, "rb") 143s 143s browser.open_fake_page(file_input_form) 143s browser.select_form() 143s 143s # Test filling an existing input and creating a new input 143s browser["first"] = value1 143s browser.new_control("file", "second", value2) 143s 143s response = browser.submit_selected() 143s > files = response.json()["files"] 143s 143s tests/test_stateful_browser.py:421: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ___________________ test_upload_file_with_malicious_default ____________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_upload_file_with_malicious_default(httpbin): 143s """Check for CVE-2023-34457 by setting the form input value directly to a 143s file that the user does not explicitly consent to upload, as a malicious 143s server might do. 143s """ 143s browser = mechanicalsoup.StatefulBrowser() 143s sensitive_path = tempfile.mkstemp()[1] 143s with open(sensitive_path, "w") as fd: 143s fd.write("Some sensitive information") 143s url = httpbin + "/post" 143s malicious_html = f""" 143s
143s 143s
143s """ 143s browser.open_fake_page(malicious_html) 143s browser.select_form() 143s response = browser.submit_selected() 143s > assert response.json()["files"] == {"malicious": ""} 143s 143s tests/test_stateful_browser.py:444: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ___________________________ test_referer_follow_link ___________________________ 143s 143s httpbin = 143s 143s def test_referer_follow_link(httpbin): 143s browser = mechanicalsoup.StatefulBrowser() 143s open_legacy_httpbin(browser, httpbin) 143s start_url = browser.url 143s > response = browser.follow_link("/headers") 143s 143s tests/test_stateful_browser.py:529: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:386: in follow_link 143s link = self._find_link_internal(link, bs4_args, 143s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 143s return self.find_link(*args, **kwargs) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s args = (), kwargs = {'url_regex': '/headers'}, links = [] 143s 143s def find_link(self, *args, **kwargs): 143s """Find and return a link, as a bs4.element.Tag object. 143s 143s The search can be refined by specifying any argument that is accepted 143s by :func:`links`. If several links match, return the first one found. 143s 143s If no link is found, raise :class:`LinkNotFoundError`. 143s """ 143s links = self.links(*args, **kwargs) 143s if len(links) == 0: 143s > raise LinkNotFoundError() 143s E mechanicalsoup.utils.LinkNotFoundError 143s 143s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 143s _____________________________ test_referer_submit ______________________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 143s s = '\n\n\n\n\n\n' 143s idx = 0 143s 143s def raw_decode(self, s, idx=0): 143s """Decode a JSON document from ``s`` (a ``str`` beginning with 143s a JSON document) and return a 2-tuple of the Python 143s representation and the index in ``s`` where the document ended. 143s 143s This can be used to decode a JSON document from a string that may 143s have extraneous data at the end. 143s 143s """ 143s try: 143s obj, end = self.scan_once(s, idx) 143s except StopIteration as err: 143s > raise JSONDecodeError("Expecting value", s, err.value) from None 143s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 143s 143s During handling of the above exception, another exception occurred: 143s 143s httpbin = 143s 143s def test_referer_submit(httpbin): 143s browser = mechanicalsoup.StatefulBrowser() 143s ref = "https://example.com/my-referer" 143s page = submit_form_headers.format(httpbin.url + "/headers") 143s browser.open_fake_page(page, url=ref) 143s browser.select_form() 143s response = browser.submit_selected() 143s > headers = response.json()["headers"] 143s 143s tests/test_stateful_browser.py:556: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s return complexjson.loads(self.text, **kwargs) 143s except JSONDecodeError as e: 143s # Catch JSON-related errors and raise as requests.JSONDecodeError 143s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 143s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 143s ____________________ test_referer_submit_override[Referer] _____________________ 143s 143s self = , kwargs = {} 143s 143s def json(self, **kwargs): 143s r"""Returns the json-encoded content of a response, if any. 143s 143s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 143s :raises requests.exceptions.JSONDecodeError: If the response body does not 143s contain valid json. 143s """ 143s 143s if not self.encoding and self.content and len(self.content) > 3: 143s # No encoding set. JSON RFC 4627 section 3 states we should expect 143s # UTF-8, -16 or -32. Detect which one to use; If the detection or 143s # decoding fails, fall back to `self.text` (using charset_normalizer to make 143s # a best guess). 143s encoding = guess_json_utf(self.content) 143s if encoding is not None: 143s try: 143s return complexjson.loads(self.content.decode(encoding), **kwargs) 143s except UnicodeDecodeError: 143s # Wrong UTF codec detected; usually because it's not UTF-8 143s # but some other 8-bit codec. This is an RFC violation, 143s # and the server didn't bother to tell us what codec *was* 143s # used. 143s pass 143s except JSONDecodeError as e: 143s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 143s 143s try: 143s > return complexjson.loads(self.text, **kwargs) 143s 143s /usr/lib/python3/dist-packages/requests/models.py:974: 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s /usr/lib/python3.13/json/__init__.py:346: in loads 143s return _default_decoder.decode(s) 143s /usr/lib/python3.13/json/decoder.py:345: in decode 143s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 143s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 143s 143s self = 144s s = '\n\n\n\n\n\n' 144s idx = 0 144s 144s def raw_decode(self, s, idx=0): 144s """Decode a JSON document from ``s`` (a ``str`` beginning with 144s a JSON document) and return a 2-tuple of the Python 144s representation and the index in ``s`` where the document ended. 144s 144s This can be used to decode a JSON document from a string that may 144s have extraneous data at the end. 144s 144s """ 144s try: 144s obj, end = self.scan_once(s, idx) 144s except StopIteration as err: 144s > raise JSONDecodeError("Expecting value", s, err.value) from None 144s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 144s 144s During handling of the above exception, another exception occurred: 144s 144s httpbin = 144s referer_header = 'Referer' 144s 144s @pytest.mark.parametrize("referer_header", ["Referer", "referer"]) 144s def test_referer_submit_override(httpbin, referer_header): 144s """Ensure the caller can override the Referer header that 144s mechanicalsoup would normally add. Because headers are case insensitive, 144s test with both 'Referer' and 'referer'. 144s """ 144s 144s browser = mechanicalsoup.StatefulBrowser() 144s ref = "https://example.com/my-referer" 144s ref_override = "https://example.com/override" 144s page = submit_form_headers.format(httpbin.url + "/headers") 144s browser.open_fake_page(page, url=ref) 144s browser.select_form() 144s response = browser.submit_selected(headers={referer_header: ref_override}) 144s > headers = response.json()["headers"] 144s 144s tests/test_stateful_browser.py:576: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s return complexjson.loads(self.text, **kwargs) 144s except JSONDecodeError as e: 144s # Catch JSON-related errors and raise as requests.JSONDecodeError 144s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 144s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 144s ____________________ test_referer_submit_override[referer] _____________________ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s > return complexjson.loads(self.text, **kwargs) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:974: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3.13/json/__init__.py:346: in loads 144s return _default_decoder.decode(s) 144s /usr/lib/python3.13/json/decoder.py:345: in decode 144s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s s = '\n\n\n\n\n\n' 144s idx = 0 144s 144s def raw_decode(self, s, idx=0): 144s """Decode a JSON document from ``s`` (a ``str`` beginning with 144s a JSON document) and return a 2-tuple of the Python 144s representation and the index in ``s`` where the document ended. 144s 144s This can be used to decode a JSON document from a string that may 144s have extraneous data at the end. 144s 144s """ 144s try: 144s obj, end = self.scan_once(s, idx) 144s except StopIteration as err: 144s > raise JSONDecodeError("Expecting value", s, err.value) from None 144s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 144s 144s During handling of the above exception, another exception occurred: 144s 144s httpbin = 144s referer_header = 'referer' 144s 144s @pytest.mark.parametrize("referer_header", ["Referer", "referer"]) 144s def test_referer_submit_override(httpbin, referer_header): 144s """Ensure the caller can override the Referer header that 144s mechanicalsoup would normally add. Because headers are case insensitive, 144s test with both 'Referer' and 'referer'. 144s """ 144s 144s browser = mechanicalsoup.StatefulBrowser() 144s ref = "https://example.com/my-referer" 144s ref_override = "https://example.com/override" 144s page = submit_form_headers.format(httpbin.url + "/headers") 144s browser.open_fake_page(page, url=ref) 144s browser.select_form() 144s response = browser.submit_selected(headers={referer_header: ref_override}) 144s > headers = response.json()["headers"] 144s 144s tests/test_stateful_browser.py:576: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s return complexjson.loads(self.text, **kwargs) 144s except JSONDecodeError as e: 144s # Catch JSON-related errors and raise as requests.JSONDecodeError 144s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 144s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 144s _________________________ test_referer_submit_headers __________________________ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s > return complexjson.loads(self.text, **kwargs) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:974: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3.13/json/__init__.py:346: in loads 144s return _default_decoder.decode(s) 144s /usr/lib/python3.13/json/decoder.py:345: in decode 144s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s s = '\n\n\n\n\n\n' 144s idx = 0 144s 144s def raw_decode(self, s, idx=0): 144s """Decode a JSON document from ``s`` (a ``str`` beginning with 144s a JSON document) and return a 2-tuple of the Python 144s representation and the index in ``s`` where the document ended. 144s 144s This can be used to decode a JSON document from a string that may 144s have extraneous data at the end. 144s 144s """ 144s try: 144s obj, end = self.scan_once(s, idx) 144s except StopIteration as err: 144s > raise JSONDecodeError("Expecting value", s, err.value) from None 144s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 144s 144s During handling of the above exception, another exception occurred: 144s 144s httpbin = 144s 144s def test_referer_submit_headers(httpbin): 144s browser = mechanicalsoup.StatefulBrowser() 144s ref = "https://example.com/my-referer" 144s page = submit_form_headers.format(httpbin.url + "/headers") 144s browser.open_fake_page(page, url=ref) 144s browser.select_form() 144s response = browser.submit_selected( 144s headers={'X-Test-Header': 'x-test-value'}) 144s > headers = response.json()["headers"] 144s 144s tests/test_stateful_browser.py:590: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s return complexjson.loads(self.text, **kwargs) 144s except JSONDecodeError as e: 144s # Catch JSON-related errors and raise as requests.JSONDecodeError 144s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 144s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 144s _____________________________ test_follow_link_ua ______________________________ 144s 144s httpbin = 144s 144s def test_follow_link_ua(httpbin): 144s """Tests passing requests parameters to follow_link() by 144s setting the User-Agent field.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s # html = 'BarLink' 144s # browser.open_fake_page(html, httpbin.url) 144s open_legacy_httpbin(browser, httpbin) 144s bs4_kwargs = {'url_regex': 'user-agent'} 144s requests_kwargs = {'headers': {"User-Agent": '007'}} 144s > resp = browser.follow_link(bs4_kwargs=bs4_kwargs, 144s requests_kwargs=requests_kwargs) 144s 144s tests/test_stateful_browser.py:642: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:386: in follow_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'user-agent'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s ______________________________ test_download_link ______________________________ 144s 144s httpbin = 144s 144s def test_download_link(httpbin): 144s """Test downloading the contents of a link to file.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s open_legacy_httpbin(browser, httpbin) 144s tmpdir = tempfile.mkdtemp() 144s tmpfile = tmpdir + '/nosuchfile.png' 144s current_url = browser.url 144s current_page = browser.page 144s > response = browser.download_link(file=tmpfile, link='image/png') 144s 144s tests/test_stateful_browser.py:669: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:412: in download_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'image/png'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s __________________________ test_download_link_nofile ___________________________ 144s 144s httpbin = 144s 144s def test_download_link_nofile(httpbin): 144s """Test downloading the contents of a link without saving it.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s open_legacy_httpbin(browser, httpbin) 144s current_url = browser.url 144s current_page = browser.page 144s > response = browser.download_link(link='image/png') 144s 144s tests/test_stateful_browser.py:688: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:412: in download_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'image/png'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s ________________________ test_download_link_nofile_bs4 _________________________ 144s 144s httpbin = 144s 144s def test_download_link_nofile_bs4(httpbin): 144s """Test downloading the contents of a link without saving it.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s open_legacy_httpbin(browser, httpbin) 144s current_url = browser.url 144s current_page = browser.page 144s > response = browser.download_link(bs4_kwargs={'url_regex': 'image.png'}) 144s 144s tests/test_stateful_browser.py:704: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:412: in download_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'image.png'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s _______________________ test_download_link_nofile_excess _______________________ 144s 144s httpbin = 144s 144s def test_download_link_nofile_excess(httpbin): 144s """Test downloading the contents of a link without saving it.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s open_legacy_httpbin(browser, httpbin) 144s current_url = browser.url 144s current_page = browser.page 144s > response = browser.download_link(url_regex='image.png') 144s 144s tests/test_stateful_browser.py:720: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:412: in download_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'image.png'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s _________________________ test_download_link_nofile_ua _________________________ 144s 144s httpbin = 144s 144s def test_download_link_nofile_ua(httpbin): 144s """Test downloading the contents of a link without saving it.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s open_legacy_httpbin(browser, httpbin) 144s current_url = browser.url 144s current_page = browser.page 144s requests_kwargs = {'headers': {"User-Agent": '007'}} 144s > response = browser.download_link(link='image/png', 144s requests_kwargs=requests_kwargs) 144s 144s tests/test_stateful_browser.py:737: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:412: in download_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'image/png'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s _____________________ test_download_link_to_existing_file ______________________ 144s 144s httpbin = 144s 144s def test_download_link_to_existing_file(httpbin): 144s """Test downloading the contents of a link to an existing file.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s open_legacy_httpbin(browser, httpbin) 144s tmpdir = tempfile.mkdtemp() 144s tmpfile = tmpdir + '/existing.png' 144s with open(tmpfile, "w") as fd: 144s fd.write("initial content") 144s current_url = browser.url 144s current_page = browser.page 144s > response = browser.download_link('image/png', tmpfile) 144s 144s tests/test_stateful_browser.py:760: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:412: in download_link 144s link = self._find_link_internal(link, bs4_args, 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:356: in _find_link_internal 144s return self.find_link(*args, **kwargs) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s args = (), kwargs = {'url_regex': 'image/png'}, links = [] 144s 144s def find_link(self, *args, **kwargs): 144s """Find and return a link, as a bs4.element.Tag object. 144s 144s The search can be refined by specifying any argument that is accepted 144s by :func:`links`. If several links match, return the first one found. 144s 144s If no link is found, raise :class:`LinkNotFoundError`. 144s """ 144s links = self.links(*args, **kwargs) 144s if len(links) == 0: 144s > raise LinkNotFoundError() 144s E mechanicalsoup.utils.LinkNotFoundError 144s 144s /usr/lib/python3/dist-packages/mechanicalsoup/stateful_browser.py:330: LinkNotFoundError 144s ____________________________ test_download_link_404 ____________________________ 144s 144s httpbin = 144s 144s def test_download_link_404(httpbin): 144s """Test downloading the contents of a broken link.""" 144s browser = mechanicalsoup.StatefulBrowser(raise_on_404=True) 144s browser.open_fake_page('Link', 144s url=httpbin.url) 144s tmpdir = tempfile.mkdtemp() 144s tmpfile = tmpdir + '/nosuchfile.txt' 144s current_url = browser.url 144s current_page = browser.page 144s > with pytest.raises(mechanicalsoup.LinkNotFoundError): 144s E Failed: DID NOT RAISE 144s 144s tests/test_stateful_browser.py:782: Failed 144s __________________________ test_download_link_referer __________________________ 144s 144s httpbin = 144s 144s def test_download_link_referer(httpbin): 144s """Test downloading the contents of a link to file.""" 144s browser = mechanicalsoup.StatefulBrowser() 144s ref = httpbin + "/my-referer" 144s browser.open_fake_page('Link', 144s url=ref) 144s tmpfile = tempfile.NamedTemporaryFile() 144s current_url = browser.url 144s current_page = browser.page 144s browser.download_link(file=tmpfile.name, link_text='Link') 144s 144s # Check that the browser state has not changed 144s assert browser.url == current_url 144s assert browser.page == current_page 144s 144s # Check that the file was downloaded 144s with open(tmpfile.name) as fd: 144s > json_data = json.load(fd) 144s 144s tests/test_stateful_browser.py:810: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3.13/json/__init__.py:293: in load 144s return loads(fp.read(), 144s /usr/lib/python3.13/json/__init__.py:346: in loads 144s return _default_decoder.decode(s) 144s /usr/lib/python3.13/json/decoder.py:345: in decode 144s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s s = '\n\n\n\n\n\n' 144s idx = 0 144s 144s def raw_decode(self, s, idx=0): 144s """Decode a JSON document from ``s`` (a ``str`` beginning with 144s a JSON document) and return a 2-tuple of the Python 144s representation and the index in ``s`` where the document ended. 144s 144s This can be used to decode a JSON document from a string that may 144s have extraneous data at the end. 144s 144s """ 144s try: 144s obj, end = self.scan_once(s, idx) 144s except StopIteration as err: 144s > raise JSONDecodeError("Expecting value", s, err.value) from None 144s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 144s ______________________ test_requests_session_and_cookies _______________________ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s > return complexjson.loads(self.text, **kwargs) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:974: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s /usr/lib/python3.13/json/__init__.py:346: in loads 144s return _default_decoder.decode(s) 144s /usr/lib/python3.13/json/decoder.py:345: in decode 144s obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = 144s s = '\n\n\n\n\n\n' 144s idx = 0 144s 144s def raw_decode(self, s, idx=0): 144s """Decode a JSON document from ``s`` (a ``str`` beginning with 144s a JSON document) and return a 2-tuple of the Python 144s representation and the index in ``s`` where the document ended. 144s 144s This can be used to decode a JSON document from a string that may 144s have extraneous data at the end. 144s 144s """ 144s try: 144s obj, end = self.scan_once(s, idx) 144s except StopIteration as err: 144s > raise JSONDecodeError("Expecting value", s, err.value) from None 144s E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3.13/json/decoder.py:363: JSONDecodeError 144s 144s During handling of the above exception, another exception occurred: 144s 144s httpbin = 144s 144s def test_requests_session_and_cookies(httpbin): 144s """Check that the session object passed to the constructor of 144s StatefulBrowser is actually taken into account.""" 144s s = requests.Session() 144s requests.utils.add_dict_to_cookiejar(s.cookies, {'key1': 'val1'}) 144s browser = mechanicalsoup.StatefulBrowser(session=s) 144s resp = browser.get(httpbin + "/cookies") 144s > assert resp.json() == {'cookies': {'key1': 'val1'}} 144s 144s tests/test_stateful_browser.py:895: 144s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 144s 144s self = , kwargs = {} 144s 144s def json(self, **kwargs): 144s r"""Returns the json-encoded content of a response, if any. 144s 144s :param \*\*kwargs: Optional arguments that ``json.loads`` takes. 144s :raises requests.exceptions.JSONDecodeError: If the response body does not 144s contain valid json. 144s """ 144s 144s if not self.encoding and self.content and len(self.content) > 3: 144s # No encoding set. JSON RFC 4627 section 3 states we should expect 144s # UTF-8, -16 or -32. Detect which one to use; If the detection or 144s # decoding fails, fall back to `self.text` (using charset_normalizer to make 144s # a best guess). 144s encoding = guess_json_utf(self.content) 144s if encoding is not None: 144s try: 144s return complexjson.loads(self.content.decode(encoding), **kwargs) 144s except UnicodeDecodeError: 144s # Wrong UTF codec detected; usually because it's not UTF-8 144s # but some other 8-bit codec. This is an RFC violation, 144s # and the server didn't bother to tell us what codec *was* 144s # used. 144s pass 144s except JSONDecodeError as e: 144s raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s 144s try: 144s return complexjson.loads(self.text, **kwargs) 144s except JSONDecodeError as e: 144s # Catch JSON-related errors and raise as requests.JSONDecodeError 144s # This aliases json.JSONDecodeError and simplejson.JSONDecodeError 144s > raise RequestsJSONDecodeError(e.msg, e.doc, e.pos) 144s E requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 144s 144s /usr/lib/python3/dist-packages/requests/models.py:978: JSONDecodeError 144s =========================== short test summary info ============================ 144s FAILED tests/test_browser.py::test__request - requests.exceptions.JSONDecodeE... 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-True-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-True-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-False-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[multipart/form-data-False-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-True-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-True-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-False-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[application/x-www-form-urlencoded-False-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-True-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-True-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-False-] 144s FAILED tests/test_browser.py::test_enctype_and_file_submit[Invalid enctype-False-] 144s FAILED tests/test_browser.py::test__request_select_none - requests.exceptions... 144s FAILED tests/test_browser.py::test__request_disabled_attr - requests.exceptio... 144s FAILED tests/test_browser.py::test_no_404 - assert 503 == 404 144s FAILED tests/test_browser.py::test_404 - Failed: DID NOT RAISE