11"""Set up functional test fixtures"""
22
3- from io import StringIO
4- from urllib import request
5- from urllib .error import HTTPError
3+ from packaging .utils import canonicalize_name
64from zest .releaser import choose
75from zest .releaser import utils
86from zest .releaser .baserelease import NOTHING_CHANGED_YET
97from zest .releaser .utils import execute_command
108from zest .releaser .utils import filename_from_test_dir
119
1210import os
11+ import requests
1312import shutil
1413import sys
1514import tarfile
@@ -35,38 +34,27 @@ def _exit(code=None):
3534
3635 sys .exit = _exit
3736
38- # Monkey patch urllib for pypi access mocking.
39- test .orig_urlopen = request . urlopen
37+ # Monkey patch the requests library for PyPI access mocking.
38+ test .orig_requests_head = requests . head
4039 test .mock_pypi_available = []
4140
42- def _make_mock_urlopen (mock_pypi_available ):
43- def _mock_urlopen (url ):
44- # print "Mock opening", url
45- package = url .replace ("https://pypi.org/simple/" , "" )
46- if package not in mock_pypi_available :
47- # On Python 3.14 we get a ResourceWarning because the HTTPError
48- # is a tempfile and we should clean it up, instead of relying
49- # on Python to do it for us. We can fix that with:
50- # with HTTPError(...) as not_found_error:
51- # raise not_found_error
52- # But that gives an error on Python 3.9:
53- # AttributeError: 'NoneType' object has no attribute 'closed'
54- # So we can only do that once we drop 3.9 support.
55- raise HTTPError (
56- url ,
57- 404 ,
58- "HTTP Error 404: Not Found (%s does not have any releases)"
59- % package ,
60- None ,
61- None ,
62- )
63- else :
64- answer = " " .join (mock_pypi_available )
65- return StringIO (answer )
66-
67- return _mock_urlopen
68-
69- request .urlopen = _make_mock_urlopen (test .mock_pypi_available )
41+ class MockResponse :
42+ def __init__ (self , ok ):
43+ self .ok = ok
44+
45+ def _make_mock_head (mock_pypi_available ):
46+ def _mock_head (url ):
47+ package = url .replace ("https://pypi.org/simple/" , "" ).replace ("/" , "" )
48+ # package my.example has been canonicalized to my-example,
49+ # so we do the same in our mock list.
50+ canonical_packages = [
51+ canonicalize_name (name ) for name in mock_pypi_available
52+ ]
53+ return MockResponse (package in canonical_packages )
54+
55+ return _mock_head
56+
57+ requests .head = _make_mock_head (test .mock_pypi_available )
7058
7159 # Extract example project
7260 example_tar = filename_from_test_dir ("example.tar" )
@@ -130,7 +118,7 @@ def rename_changelog(src: str, dst: str):
130118
131119def teardown (test ):
132120 sys .exit = test .orig_exit
133- request . urlopen = test .orig_urlopen
121+ requests . head = test .orig_requests_head
134122 os .chdir (test .orig_dir )
135123 sys .argv [1 :] = test .orig_argv
136124 shutil .rmtree (test .tempdir )
0 commit comments