def run_egg_info(self, force_root_egg_info=False): assert self.source_dir if self.name: logger.notify( 'Running setup.py (path:%s) egg_info for package %s' % (self.setup_py, self.name) ) else: logger.notify( 'Running setup.py (path:%s) egg_info for package from %s' % (self.setup_py, self.url) ) logger.indent += 2 try: # if it's distribute>=0.7, it won't contain an importable # setuptools, and having an egg-info dir blocks the ability of # setup.py to find setuptools plugins, so delete the egg-info dir # if no setuptools. it will get recreated by the run of egg_info # NOTE: this self.name check only works when installing from a # specifier (not archive path/urls) # TODO: take this out later if (self.name == 'distribute' and not os.path.isdir( os.path.join(self.source_dir, 'setuptools'))): rmtree(os.path.join(self.source_dir, 'distribute.egg-info')) script = self._run_setup_py script = script.replace('__SETUP_PY__', repr(self.setup_py)) script = script.replace('__PKG_NAME__', repr(self.name)) egg_info_cmd = [sys.executable, '-c', script, 'egg_info'] # We can't put the .egg-info files at the root, because then the # source code will be mistaken for an installed egg, causing # problems if self.editable or force_root_egg_info: egg_base_option = [] else: egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info') if not os.path.exists(egg_info_dir): os.makedirs(egg_info_dir) egg_base_option = ['--egg-base', 'pip-egg-info'] cwd = self.source_dir if self.editable_options and \ 'subdirectory' in self.editable_options: cwd = os.path.join(cwd, self.editable_options['subdirectory']) call_subprocess( egg_info_cmd + egg_base_option, cwd=cwd, filter_stdout=self._filter_install, show_stdout=False, command_level=logger.VERBOSE_DEBUG, command_desc='python setup.py egg_info') finally: logger.indent -= 2 if not self.req: self.req = pkg_resources.Requirement.parse( "%(Name)s==%(Version)s" % self.pkg_info()) self.correct_build_location()
def check_destination(self, dest, url, rev_options, rev_display): """ Prepare a location to receive a checkout/clone. Return True if the location is ready for (and requires) a checkout/clone, False otherwise. """ checkout = True prompt = False if os.path.exists(dest): checkout = False if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): logger.info('%s in %s exists, and has correct URL (%s)' % (self.repo_name.title(), display_path(dest), url)) logger.notify('Updating %s %s%s' % (display_path(dest), self.repo_name, rev_display)) self.update(dest, rev_options) else: logger.warn('%s %s in %s exists with URL %s' % (self.name, self.repo_name, display_path(dest), existing_url)) prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) else: logger.warn('Directory %s already exists, ' 'and is not a %s %s.' % (dest, self.name, self.repo_name)) prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: logger.warn('The plan is to install the %s repository %s' % (self.name, url)) response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) if response == 's': logger.notify('Switching %s %s to %s%s' % (self.repo_name, display_path(dest), url, rev_display)) self.switch(dest, url, rev_options) elif response == 'i': # do nothing pass elif response == 'w': logger.warn('Deleting %s' % display_path(dest)) rmtree(dest) checkout = True elif response == 'b': dest_dir = backup_dir(dest) logger.warn('Backing up %s to %s' % (display_path(dest), dest_dir)) shutil.move(dest, dest_dir) checkout = True return checkout
def zip_package(self, module_name, filename, no_pyc): orig_filename = filename logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) logger.indent += 2 if filename.endswith('.egg'): dest_filename = filename else: dest_filename = filename + '.zip' try: # FIXME: I think this needs to be undoable: if filename == dest_filename: filename = backup_dir(orig_filename) logger.notify( 'Moving %s aside to %s' % (orig_filename, filename) ) if not self.simulate: shutil.move(orig_filename, filename) try: logger.info( 'Creating zip file in %s' % display_path(dest_filename) ) if not self.simulate: zip = zipfile.ZipFile(dest_filename, 'w') zip.writestr(module_name + '/', '') for dirpath, dirnames, filenames in os.walk(filename): if no_pyc: filenames = [f for f in filenames if not f.lower().endswith('.pyc')] for fns, is_dir in [ (dirnames, True), (filenames, False)]: for fn in fns: full = os.path.join(dirpath, fn) dest = os.path.join( module_name, dirpath[len(filename):].lstrip( os.path.sep ), fn, ) if is_dir: zip.writestr(dest + '/', '') else: zip.write(full, dest) zip.close() logger.info( 'Removing old directory %s' % display_path(filename) ) if not self.simulate: rmtree(filename) except: # FIXME: need to do an undo here raise # FIXME: should also be undone: self.add_filename_to_pth(dest_filename) finally: logger.indent -= 2
def create_venv(dest_dir): if os.path.exists(dest_dir): rmtree(dest_dir) print('Creating virtualenv in %s' % dest_dir) code = subprocess.check_call([ 'virtualenv', '--no-site-packages', dest_dir, ]) assert not code, "virtualenv failed"
def export(self, location): """Export the Hg repository at the url to the destination location""" temp_dir = tempfile.mkdtemp('-export', 'pip-') self.unpack(temp_dir) try: call_subprocess( [self.cmd, 'archive', location], filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) finally: rmtree(temp_dir)
def unpack_file_url(link, location): source = url_to_path(link.url) content_type = mimetypes.guess_type(source)[0] if os.path.isdir(source): # delete the location since shutil will create it again :( if os.path.isdir(location): rmtree(location) copytree(source, location) else: unpack_file(source, location, content_type, link)
def test_uninstall_editable_with_source_outside_venv(): """ Test uninstalling editable install from existing source outside the venv. """ try: temp = mkdtemp() tmpdir = join(temp, 'virtualenv') _test_uninstall_editable_with_source_outside_venv(tmpdir) finally: rmtree(temp)
def remove_temporary_source(self): """Remove the source files from this requirement, if they are marked for deletion""" if self.is_bundle or os.path.exists(self.delete_marker_filename): logger.info('Removing source in %s' % self.source_dir) if self.source_dir: rmtree(self.source_dir) self.source_dir = None if self._temp_build_dir and os.path.exists(self._temp_build_dir): rmtree(self._temp_build_dir) self._temp_build_dir = None
def export(self, location): """Export the Git repository at the url to the destination location""" temp_dir = tempfile.mkdtemp('-export', 'pip-') self.unpack(temp_dir) try: if not location.endswith('/'): location = location + '/' call_subprocess( [self.cmd, 'checkout-index', '-a', '-f', '--prefix', location], filter_stdout=self._filter, show_stdout=False, cwd=temp_dir) finally: rmtree(temp_dir)
def export(self, location): """Export the Bazaar repository at the url to the destination location""" temp_dir = tempfile.mkdtemp('-export', 'pip-') self.unpack(temp_dir) if os.path.exists(location): # Remove the location to make sure Bazaar can export it correctly rmtree(location) try: call_subprocess([self.cmd, 'export', location], cwd=temp_dir, filter_stdout=self._filter, show_stdout=False) finally: rmtree(temp_dir)
def install_setuptools(env): easy_install = os.path.join(env.bin_path, 'easy_install') version = 'setuptools==0.6c11' if sys.platform != 'win32': return env.run(easy_install, version) tempdir = tempfile.mkdtemp() try: for f in glob.glob(easy_install+'*'): shutil.copy2(f, tempdir) return env.run(os.path.join(tempdir, 'easy_install'), version) finally: rmtree(tempdir)
def test_uninstall_editable_with_source_outside_venv(script, tmpdir): """ Test uninstalling editable install from existing source outside the venv. """ cache_dir = tmpdir.join("cache") try: temp = mkdtemp() tmpdir = join(temp, 'virtualenv') _test_uninstall_editable_with_source_outside_venv(script, tmpdir, cache_dir) finally: rmtree(temp)
def unpack_file_url(link, location, download_dir=None): link_path = url_to_path(link.url_without_fragment) already_downloaded = False # If it's a url to a local directory if os.path.isdir(link_path): if os.path.isdir(location): rmtree(location) shutil.copytree(link_path, location, symlinks=True) return # if link has a hash, let's confirm it matches if link.hash: link_path_hash = _get_hash_from_file(link_path, link) _check_hash(link_path_hash, link) # If a download dir is specified, is the file already there and valid? if download_dir: download_path = os.path.join(download_dir, link.filename) if os.path.exists(download_path): content_type = mimetypes.guess_type(download_path)[0] logger.notify('File was already downloaded %s' % download_path) if link.hash: download_hash = _get_hash_from_file(download_path, link) try: _check_hash(download_hash, link) already_downloaded = True except HashMismatch: logger.warn( 'Previously-downloaded file %s has bad hash, ' 're-downloading.' % link_path ) os.unlink(download_path) else: already_downloaded = True if already_downloaded: from_path = download_path else: from_path = link_path content_type = mimetypes.guess_type(from_path)[0] # unpack the archive to the build dir location. even when only downloading # archives, they have to be unpacked to parse dependencies unpack_file(from_path, location, content_type, link) # a download dir is specified and not already downloaded if download_dir and not already_downloaded: _copy_file(from_path, download_dir, content_type, link)
def _test_packages(output, pending_fn): package = get_last_item(pending_fn) print('Testing package %s' % package) dest_dir = os.path.join(output, package) print('Creating virtualenv in %s' % dest_dir) create_venv(dest_dir) print('Uninstalling actual pip') code = subprocess.check_call([ os.path.join(dest_dir, bin_dir, 'pip'), 'uninstall', '-y', 'pip', ]) assert not code, 'pip uninstallation failed' print('Installing development pip') code = subprocess.check_call( [ os.path.join(dest_dir, bin_dir, 'python'), 'setup.py', 'install' ], cwd=src_folder, ) assert not code, 'pip installation failed' print('Trying installation of %s' % dest_dir) code = subprocess.check_call([ os.path.join(dest_dir, bin_dir, 'pip'), 'install', package, ]) if code: print('Installation of %s failed' % package) print('Now checking easy_install...') create_venv(dest_dir) code = subprocess.check_call([ os.path.join(dest_dir, bin_dir, 'easy_install'), package, ]) if code: print('easy_install also failed') add_package(os.path.join(output, 'easy-failure.txt'), package) else: print('easy_install succeeded') add_package(os.path.join(output, 'failure.txt'), package) pop_last_item(pending_fn, package) else: print('Installation of %s succeeded' % package) add_package(os.path.join(output, 'success.txt'), package) pop_last_item(pending_fn, package) rmtree(dest_dir)
def test_install_curdir(script, data): """ Test installing current directory ('.'). """ run_from = data.packages.join("FSPkg") # Python 2.4 Windows balks if this exists already egg_info = join(run_from, "FSPkg.egg-info") if os.path.isdir(egg_info): rmtree(egg_info) result = script.pip('install', curdir, cwd=run_from, expect_error=False) fspkg_folder = script.site_packages/'fspkg' egg_info_folder = script.site_packages/'FSPkg-0.1dev-py%s.egg-info' % pyversion assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result)
def export(self, location): """Export the svn repository at the url to the destination location""" url, rev = self.get_url_rev() logger.notify('Exporting svn repository %s to %s' % (url, location)) logger.indent += 2 try: if os.path.exists(location): # Subversion doesn't like to check out over an existing directory # --force fixes this, but was only added in svn 1.5 rmtree(location) call_subprocess( [self.cmd, 'export', url, location], filter_stdout=self._filter, show_stdout=False) finally: logger.indent -= 2
def test_install_curdir(): """ Test installing current directory ('.'). """ env = reset_env() run_from = abspath(join(here, 'packages', 'FSPkg')) # Python 2.4 Windows balks if this exists already egg_info = join(run_from, "FSPkg.egg-info") if os.path.isdir(egg_info): rmtree(egg_info) result = run_pip('install', curdir, cwd=run_from, expect_error=False) fspkg_folder = env.site_packages / 'fspkg' egg_info_folder = env.site_packages / 'FSPkg-0.1dev-py%s.egg-info' % pyversion assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result)
def test_install_curdir(): """ Test installing current directory ('.'). """ env = reset_env() run_from = abspath(join(here, 'packages', 'FSPkg')) # Python 2.4 Windows balks if this exists already egg_info = join(run_from, "FSPkg.egg-info") if os.path.isdir(egg_info): rmtree(egg_info) result = run_pip('install', curdir, cwd=run_from, expect_error=False) fspkg_folder = env.site_packages/'fspkg' egg_info_folder = env.site_packages/'FSPkg-0.1dev-py%s.egg-info' % pyversion assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result)
def export(self, location): """Export the svn repository at the url to the destination location""" url, rev = self.get_url_rev() logger.notify('Exporting svn repository %s to %s' % (url, location)) logger.indent += 2 try: if os.path.exists(location): # Subversion doesn't like to check out over an existing directory # --force fixes this, but was only added in svn 1.5 rmtree(location) call_subprocess([self.cmd, 'export', url, location], filter_stdout=self._filter, show_stdout=False) finally: logger.indent -= 2
def test_install_curdir(script, data): """ Test installing current directory ('.'). """ run_from = data.packages.join("FSPkg") # Python 2.4 Windows balks if this exists already egg_info = join(run_from, "FSPkg.egg-info") if os.path.isdir(egg_info): rmtree(egg_info) result = script.pip('install', curdir, cwd=run_from, expect_error=False) fspkg_folder = script.site_packages / 'fspkg' egg_info_folder = (script.site_packages / 'FSPkg-0.1dev-py%s.egg-info' % pyversion) assert fspkg_folder in result.files_created, str(result.stdout) assert egg_info_folder in result.files_created, str(result)
def export(self, location): """ Export the Bazaar repository at the url to the destination location """ temp_dir = tempfile.mkdtemp('-export', 'pip-') self.unpack(temp_dir) if os.path.exists(location): # Remove the location to make sure Bazaar can export it correctly rmtree(location) try: call_subprocess([self.cmd, 'export', location], cwd=temp_dir, filter_stdout=self._filter, show_stdout=False) finally: rmtree(temp_dir)
def test_uninstall_editable_with_source_outside_venv(script, tmpdir): """ Test uninstalling editable install from existing source outside the venv. """ cache_dir = tmpdir.join("cache") try: temp = mkdtemp() tmpdir = join(temp, 'pip-test-package') _test_uninstall_editable_with_source_outside_venv( script, tmpdir, cache_dir, ) finally: rmtree(temp)
def cleanup_files(self): """Clean up files, remove builds.""" logger.notify('Cleaning up...') logger.indent += 2 for req in self.reqs_to_cleanup: req.remove_temporary_source() remove_dir = [] if self._pip_has_created_build_dir(): remove_dir.append(self.build_dir) for dir in remove_dir: if os.path.exists(dir): logger.info('Removing temporary dir %s...' % dir) rmtree(dir) logger.indent -= 2
def _test_packages(output, pending_fn): package = get_last_item(pending_fn) print('Testing package %s' % package) dest_dir = os.path.join(output, package) print('Creating virtualenv in %s' % dest_dir) create_venv(dest_dir) print('Uninstalling actual pip') code = subprocess.check_call([ os.path.join(dest_dir, bin_dir, 'pip'), 'uninstall', '-y', 'pip', ]) assert not code, 'pip uninstallation failed' print('Installing development pip') code = subprocess.check_call( [os.path.join(dest_dir, bin_dir, 'python'), 'setup.py', 'install'], cwd=src_folder, ) assert not code, 'pip installation failed' print('Trying installation of %s' % dest_dir) code = subprocess.check_call([ os.path.join(dest_dir, bin_dir, 'pip'), 'install', package, ]) if code: print('Installation of %s failed' % package) print('Now checking easy_install...') create_venv(dest_dir) code = subprocess.check_call([ os.path.join(dest_dir, bin_dir, 'easy_install'), package, ]) if code: print('easy_install also failed') add_package(os.path.join(output, 'easy-failure.txt'), package) else: print('easy_install succeeded') add_package(os.path.join(output, 'failure.txt'), package) pop_last_item(pending_fn, package) else: print('Installation of %s succeeded' % package) add_package(os.path.join(output, 'success.txt'), package) pop_last_item(pending_fn, package) rmtree(dest_dir)
def zip_package(self, module_name, filename, no_pyc): orig_filename = filename logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) logger.indent += 2 if filename.endswith('.egg'): dest_filename = filename else: dest_filename = filename + '.zip' try: ## FIXME: I think this needs to be undoable: if filename == dest_filename: filename = backup_dir(orig_filename) logger.notify('Moving %s aside to %s' % (orig_filename, filename)) if not self.simulate: shutil.move(orig_filename, filename) try: logger.info('Creating zip file in %s' % display_path(dest_filename)) if not self.simulate: zip = zipfile.ZipFile(dest_filename, 'w') zip.writestr(module_name + '/', '') for dirpath, dirnames, filenames in os.walk(filename): if no_pyc: filenames = [f for f in filenames if not f.lower().endswith('.pyc')] for fns, is_dir in [(dirnames, True), (filenames, False)]: for fn in fns: full = os.path.join(dirpath, fn) dest = os.path.join(module_name, dirpath[len(filename):].lstrip(os.path.sep), fn) if is_dir: zip.writestr(dest + '/', '') else: zip.write(full, dest) zip.close() logger.info('Removing old directory %s' % display_path(filename)) if not self.simulate: rmtree(filename) except: ## FIXME: need to do an undo here raise ## FIXME: should also be undone: self.add_filename_to_pth(dest_filename) finally: logger.indent -= 2
def cleanup_files(self, bundle=False): """Clean up files, remove builds.""" logger.notify('Cleaning up...') logger.indent += 2 for req in self.reqs_to_cleanup: req.remove_temporary_source() remove_dir = [] if self._pip_has_created_build_dir(): remove_dir.append(self.build_dir) # The source dir of a bundle can always be removed. # FIXME: not if it pre-existed the bundle! if bundle: remove_dir.append(self.src_dir) for dir in remove_dir: if os.path.exists(dir): logger.info('Removing temporary dir %s...' % dir) rmtree(dir) logger.indent -= 2
def prepare_files(self, finder, **kwargs): wheel_dir = CacheOpts().wheelhouse self.wheel_download_dir = wheel_dir super(FasterRequirementSet, self).prepare_files(finder, **kwargs) # build wheels before install. wb = FasterWheelBuilder( self, finder, wheel_dir=wheel_dir, ) # TODO-TEST: we only incur the build cost once on uncached install for req in wb.build(): link = optimistic_wheel_search(req, finder.find_links) if link is None: logger.error('SLOW!! no wheel found after building (couldn\'t be wheeled?): %s', req) continue # replace the setup.py "sdist" with the wheel "bdist" from pip.util import rmtree, unzip_file rmtree(req.source_dir) unzip_file(link.path, req.source_dir, flatten=False) req.url = link.url
def _cleanup(): global env del env rmtree(download_cache, ignore_errors=True) rmtree(fast_test_env_root, ignore_errors=True) rmtree(fast_test_env_backup, ignore_errors=True)
def commit(self): """Remove temporary save dir: rollback will no longer be possible.""" if self.save_dir is not None: rmtree(self.save_dir) self.save_dir = None self._moved_paths = []
def __del__(self): rmtree(str(self.root_path), ignore_errors=True)
def __init__(self, environ=None, sitecustomize=None, pypi_cache=True): import virtualenv self.root_path = fast_test_env_root self.backup_path = fast_test_env_backup self.scratch_path = self.root_path / self.scratch # We will set up a virtual environment at root_path. self.venv_path = self.root_path / self.venv if not environ: environ = os.environ.copy() environ = clear_environ(environ) environ['PIP_DOWNLOAD_CACHE'] = str(download_cache) environ['PIP_NO_INPUT'] = '1' environ['PIP_LOG_FILE'] = str(self.root_path/'pip-log.txt') TestFileEnvironment.__init__(self, self.root_path, ignore_hidden=False, environ=environ, split_cmd=False, start_clear=False, cwd=self.scratch_path, capture_temp=True, assert_no_temp=True) virtualenv_paths = virtualenv.path_locations(self.venv_path) for id, path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths): #fix for virtualenv issue #306 if hasattr(sys, "pypy_version_info") and id == 'lib': path = os.path.join(self.venv_path, 'lib-python', pyversion) setattr(self, id+'_path', Path(path)) setattr(self, id, relpath(self.root_path, path)) assert self.venv == TestPipEnvironment.venv # sanity check if hasattr(sys, "pypy_version_info"): self.site_packages = self.venv/'site-packages' else: self.site_packages = self.lib/'site-packages' self.user_base_path = self.venv_path/'user' self.user_site_path = self.venv_path/'user'/site_packages_suffix self.user_site = relpath(self.root_path, self.user_site_path) self.environ["PYTHONUSERBASE"] = self.user_base_path # put the test-scratch virtualenv's bin dir first on the PATH self.environ['PATH'] = Path.pathsep.join((self.bin_path, self.environ['PATH'])) if self.root_path.exists: rmtree(self.root_path) if self.backup_path.exists and not self.rebuild_venv: shutil.copytree(self.backup_path, self.root_path, True) else: demand_dirs(self.venv_path) demand_dirs(self.scratch_path) # Create a virtualenv and remember where it's putting things. create_virtualenv(self.venv_path) demand_dirs(self.user_site_path) # create easy-install.pth in user_site, so we always have it updated instead of created open(self.user_site_path/'easy-install.pth', 'w').close() # test that test-scratch virtualenv creation produced sensible venv python result = self.run('python', '-c', 'import sys; print(sys.executable)') pythonbin = result.stdout.strip() if Path(pythonbin).noext != self.bin_path/'python': raise RuntimeError( "Oops! 'python' in our test environment runs %r" " rather than expected %r" % (pythonbin, self.bin_path/'python')) # Uninstall whatever version of pip came with the virtualenv. # Earlier versions of pip were incapable of # self-uninstallation on Windows, so we use the one we're testing. self.run('python', '-c', '"import sys; sys.path.insert(0, %r); import pip; sys.exit(pip.main());"' % src_folder, 'uninstall', '-vvv', '-y', 'pip') # Install this version instead self.run('python', 'setup.py', 'install', cwd=src_folder, expect_stderr=True) # make the backup (remove previous backup if exists) if self.backup_path.exists: rmtree(self.backup_path) shutil.copytree(self.root_path, self.backup_path, True) #create sitecustomize.py and add patches self._create_empty_sitecustomize() if pypi_cache: self._use_cached_pypi_server() if sitecustomize: self._add_to_sitecustomize(sitecustomize) assert self.root_path.exists # Ensure that $TMPDIR exists (because we use start_clear=False, it's not created for us) if self.temp_path and not os.path.exists(self.temp_path): os.makedirs(self.temp_path)
def unpack(self, location): if os.path.exists(location): rmtree(location) self.obtain(location)
def rmtree(self, noerrors=True): """ Removes a directory tree. Ignores errors by default. """ return rmtree(self, ignore_errors=noerrors)
def __init__(self, environ=None): import virtualenv self.root_path = fast_test_env_root self.backup_path = fast_test_env_backup self.scratch_path = self.root_path / self.scratch # We will set up a virtual environment at root_path. self.venv_path = self.root_path / self.venv if not environ: environ = os.environ.copy() environ = clear_environ(environ) environ['PIP_DOWNLOAD_CACHE'] = str(download_cache) environ['PIP_NO_INPUT'] = '1' environ['PIP_LOG_FILE'] = str(self.root_path/'pip-log.txt') TestFileEnvironment.__init__(self, self.root_path, ignore_hidden=False, environ=environ, split_cmd=False, start_clear=False, cwd=self.scratch_path, capture_temp=True, assert_no_temp=True) virtualenv_paths = virtualenv.path_locations(self.venv_path) for id, path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths): setattr(self, id+'_path', Path(path)) setattr(self, id, relpath(self.root_path, path)) assert self.venv == TestPipEnvironment.venv # sanity check self.site_packages = self.lib/'site-packages' self.user_base_path = self.venv_path/'user' self.user_site_path = self.venv_path/'user'/'lib'/self.lib.name/'site-packages' self.user_site = relpath(self.root_path, self.user_site_path) self.environ["PYTHONUSERBASE"] = self.user_base_path # put the test-scratch virtualenv's bin dir first on the PATH self.environ['PATH'] = Path.pathsep.join((self.bin_path, self.environ['PATH'])) if self.root_path.exists: rmtree(self.root_path) if self.backup_path.exists: shutil.copytree(self.backup_path, self.root_path, True) else: demand_dirs(self.venv_path) demand_dirs(self.scratch_path) use_distribute = os.environ.get('PIP_TEST_USE_DISTRIBUTE', False) # Create a virtualenv and remember where it's putting things. create_virtualenv(self.venv_path, distribute=use_distribute) demand_dirs(self.user_site_path) # create easy-install.pth in user_site, so we always have it updated instead of created open(self.user_site_path/'easy-install.pth', 'w').close() # test that test-scratch virtualenv creation produced sensible venv python result = self.run('python', '-c', 'import sys; print(sys.executable)') pythonbin = result.stdout.strip() if Path(pythonbin).noext != self.bin_path/'python': raise RuntimeError( "Oops! 'python' in our test environment runs %r" " rather than expected %r" % (pythonbin, self.bin_path/'python')) # make sure we have current setuptools to avoid svn incompatibilities if not use_distribute: install_setuptools(self) # Uninstall whatever version of pip came with the virtualenv. # Earlier versions of pip were incapable of # self-uninstallation on Windows, so we use the one we're testing. self.run('python', '-c', '"import sys; sys.path.insert(0, %r); import pip; sys.exit(pip.main());"' % os.path.dirname(here), 'uninstall', '-vvv', '-y', 'pip') # Install this version instead self.run('python', 'setup.py', 'install', cwd=src_folder, expect_stderr=True) shutil.copytree(self.root_path, self.backup_path, True) self._use_cached_pypi_server() assert self.root_path.exists
def __init__(self, environ=None, sitecustomize=None): import virtualenv self.root_path = fast_test_env_root self.backup_path = fast_test_env_backup self.scratch_path = self.root_path / self.scratch # We will set up a virtual environment at root_path. self.venv_path = self.root_path / self.venv if not environ: environ = os.environ.copy() environ = clear_environ(environ) environ['PIP_DOWNLOAD_CACHE'] = str(download_cache) environ['PIP_NO_INPUT'] = '1' environ['PIP_LOG_FILE'] = str(self.root_path / 'pip-log.txt') TestFileEnvironment.__init__(self, self.root_path, ignore_hidden=False, environ=environ, split_cmd=False, start_clear=False, cwd=self.scratch_path, capture_temp=True, assert_no_temp=True) virtualenv_paths = virtualenv.path_locations(self.venv_path) for id, path in zip(('venv', 'lib', 'include', 'bin'), virtualenv_paths): #fix for virtualenv issue #306 if hasattr(sys, "pypy_version_info") and id == 'lib': path = os.path.join(self.venv_path, 'lib-python', pyversion) setattr(self, id + '_path', Path(path)) setattr(self, id, relpath(self.root_path, path)) assert self.venv == TestPipEnvironment.venv # sanity check if hasattr(sys, "pypy_version_info"): self.site_packages = self.venv / 'site-packages' else: self.site_packages = self.lib / 'site-packages' self.user_base_path = self.venv_path / 'user' self.user_site_path = self.venv_path / 'user' / 'lib' / self.lib.name / 'site-packages' self.user_site = relpath(self.root_path, self.user_site_path) self.environ["PYTHONUSERBASE"] = self.user_base_path # put the test-scratch virtualenv's bin dir first on the PATH self.environ['PATH'] = Path.pathsep.join( (self.bin_path, self.environ['PATH'])) self.use_distribute = os.environ.get('PIP_TEST_USE_DISTRIBUTE', False) if self.root_path.exists: rmtree(self.root_path) if self.backup_path.exists: shutil.copytree(self.backup_path, self.root_path, True) else: demand_dirs(self.venv_path) demand_dirs(self.scratch_path) # Create a virtualenv and remember where it's putting things. create_virtualenv(self.venv_path, distribute=self.use_distribute) demand_dirs(self.user_site_path) # create easy-install.pth in user_site, so we always have it updated instead of created open(self.user_site_path / 'easy-install.pth', 'w').close() # test that test-scratch virtualenv creation produced sensible venv python result = self.run('python', '-c', 'import sys; print(sys.executable)') pythonbin = result.stdout.strip() if Path(pythonbin).noext != self.bin_path / 'python': raise RuntimeError( "Oops! 'python' in our test environment runs %r" " rather than expected %r" % (pythonbin, self.bin_path / 'python')) # make sure we have current setuptools to avoid svn incompatibilities if not self.use_distribute: install_setuptools(self) # Uninstall whatever version of pip came with the virtualenv. # Earlier versions of pip were incapable of # self-uninstallation on Windows, so we use the one we're testing. self.run( 'python', '-c', '"import sys; sys.path.insert(0, %r); import pip; sys.exit(pip.main());"' % os.path.dirname(here), 'uninstall', '-vvv', '-y', 'pip') # Install this version instead self.run('python', 'setup.py', 'install', cwd=src_folder, expect_stderr=True) # Install snakebasket as well self.run('python', 'setup.py', 'install', cwd=os.path.abspath(os.path.join(src_folder, '../')), expect_stderr=True) # Backup up test dir shutil.copytree(self.root_path, self.backup_path, True) #create sitecustomize.py and add patches self._create_empty_sitecustomize() self._use_cached_pypi_server() if sitecustomize: self._add_to_sitecustomize(sitecustomize) assert self.root_path.exists # Ensure that $TMPDIR exists (because we use start_clear=False, it's not created for us) if self.temp_path and not os.path.exists(self.temp_path): os.makedirs(self.temp_path)
def create_venv(dest_dir): if os.path.exists(dest_dir): rmtree(dest_dir) print('Creating virtualenv in %s' % dest_dir) code = subprocess.check_call(['virtualenv', '--no-site-packages', dest_dir]) assert not code, "virtualenv failed"
def _cleanup(): global env del env rmtree(download_cache, ignore_errors=True)