1import os 2import sys 3import subprocess 4from urllib.request import urlopen 5from urllib.error import URLError 6 7import pathlib 8 9import pytest 10 11from . import contexts 12from .textwrap import DALS 13from .test_easy_install import make_nspkg_sdist 14 15 16@pytest.fixture(autouse=True) 17def pytest_virtualenv_works(venv): 18 """ 19 pytest_virtualenv may not work. if it doesn't, skip these 20 tests. See #1284. 21 """ 22 venv_prefix = venv.run(["python" , "-c", "import sys; print(sys.prefix)"]).strip() 23 if venv_prefix == sys.prefix: 24 pytest.skip("virtualenv is broken (see pypa/setuptools#1284)") 25 26 27def test_clean_env_install(venv_without_setuptools, setuptools_wheel): 28 """ 29 Check setuptools can be installed in a clean environment. 30 """ 31 cmd = ["python", "-m", "pip", "install", str(setuptools_wheel)] 32 venv_without_setuptools.run(cmd) 33 34 35def access_pypi(): 36 # Detect if tests are being run without connectivity 37 if not os.environ.get('NETWORK_REQUIRED', False): # pragma: nocover 38 try: 39 urlopen('https://pypi.org', timeout=1) 40 except URLError: 41 # No network, disable most of these tests 42 return False 43 44 return True 45 46 47@pytest.mark.skipif( 48 'platform.python_implementation() == "PyPy"', 49 reason="https://github.com/pypa/setuptools/pull/2865#issuecomment-965834995", 50) 51@pytest.mark.skipif(not access_pypi(), reason="no network") 52# ^-- Even when it is not necessary to install a different version of `pip` 53# the build process will still try to download `wheel`, see #3147 and #2986. 54@pytest.mark.parametrize( 55 'pip_version', 56 [ 57 None, 58 pytest.param('pip<20', marks=pytest.mark.xfail(reason='pypa/pip#6599')), 59 'pip<20.1', 60 'pip<21', 61 'pip<22', 62 pytest.param( 63 'https://github.com/pypa/pip/archive/main.zip', 64 marks=pytest.mark.xfail(reason='#2975'), 65 ), 66 ] 67) 68def test_pip_upgrade_from_source(pip_version, venv_without_setuptools, 69 setuptools_wheel, setuptools_sdist): 70 """ 71 Check pip can upgrade setuptools from source. 72 """ 73 # Install pip/wheel, in a venv without setuptools (as it 74 # should not be needed for bootstraping from source) 75 venv = venv_without_setuptools 76 venv.run(["pip", "install", "-U", "wheel"]) 77 if pip_version is not None: 78 venv.run(["python", "-m", "pip", "install", "-U", pip_version, "--retries=1"]) 79 with pytest.raises(subprocess.CalledProcessError): 80 # Meta-test to make sure setuptools is not installed 81 venv.run(["python", "-c", "import setuptools"]) 82 83 # Then install from wheel. 84 venv.run(["pip", "install", str(setuptools_wheel)]) 85 # And finally try to upgrade from source. 86 venv.run(["pip", "install", "--no-cache-dir", "--upgrade", str(setuptools_sdist)]) 87 88 89def _check_test_command_install_requirements(venv, tmpdir): 90 """ 91 Check the test command will install all required dependencies. 92 """ 93 def sdist(distname, version): 94 dist_path = tmpdir.join('%s-%s.tar.gz' % (distname, version)) 95 make_nspkg_sdist(str(dist_path), distname, version) 96 return dist_path 97 dependency_links = [ 98 pathlib.Path(str(dist_path)).as_uri() 99 for dist_path in ( 100 sdist('foobar', '2.4'), 101 sdist('bits', '4.2'), 102 sdist('bobs', '6.0'), 103 sdist('pieces', '0.6'), 104 ) 105 ] 106 with tmpdir.join('setup.py').open('w') as fp: 107 fp.write(DALS( 108 ''' 109 from setuptools import setup 110 111 setup( 112 dependency_links={dependency_links!r}, 113 install_requires=[ 114 'barbazquux1; sys_platform in ""', 115 'foobar==2.4', 116 ], 117 setup_requires='bits==4.2', 118 tests_require=""" 119 bobs==6.0 120 """, 121 extras_require={{ 122 'test': ['barbazquux2'], 123 ':"" in sys_platform': 'pieces==0.6', 124 ':python_version > "1"': """ 125 pieces 126 foobar 127 """, 128 }} 129 ) 130 '''.format(dependency_links=dependency_links))) 131 with tmpdir.join('test.py').open('w') as fp: 132 fp.write(DALS( 133 ''' 134 import foobar 135 import bits 136 import bobs 137 import pieces 138 139 open('success', 'w').close() 140 ''')) 141 142 cmd = ["python", 'setup.py', 'test', '-s', 'test'] 143 venv.run(cmd, cwd=str(tmpdir)) 144 assert tmpdir.join('success').check() 145 146 147def test_test_command_install_requirements(venv, tmpdir, tmpdir_cwd): 148 # Ensure pip/wheel packages are installed. 149 venv.run(["python", "-c", "__import__('pkg_resources').require(['pip', 'wheel'])"]) 150 # disable index URL so bits and bobs aren't requested from PyPI 151 with contexts.environment(PYTHONPATH=None, PIP_NO_INDEX="1"): 152 _check_test_command_install_requirements(venv, tmpdir) 153 154 155def test_no_missing_dependencies(bare_venv, request): 156 """ 157 Quick and dirty test to ensure all external dependencies are vendored. 158 """ 159 setuptools_dir = request.config.rootdir 160 for command in ('upload',): # sorted(distutils.command.__all__): 161 bare_venv.run(['python', 'setup.py', command, '-h'], cwd=setuptools_dir) 162