def test_version_incompatibility(self): class Warner(object): def __call__(self, wheel_version, file_version): self.wheel_version = wheel_version self.file_version = file_version fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) warner = Warner() maker = ScriptMaker(None, None) w.install(paths, maker, warner=warner) self.assertEqual(warner.wheel_version, w.wheel_version) self.assertEqual(warner.file_version, (2, 0)) # Now set the wheel's instance to the higher value and ensure # warner isn't called warner = Warner() w.wheel_version = (2, 0) w.install(paths, maker, warner=warner) self.assertFalse(hasattr(warner, 'wheel_version')) self.assertFalse(hasattr(warner, 'file_version'))
def test_custom_executable(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') for executable in 'mypython', None: dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) maker = ScriptMaker(None, None) maker.variants = set(['']) maker.executable = executable w.install(paths, maker) # On Windows there will be an exe file, and on POSIX a text file. # The test is structured to not care. p = paths['scripts'] # there should be just one file in the directory - dummy.py/dummy.exe p = os.path.join(p, os.listdir(p)[0]) with open(p, 'rb') as f: data = f.read() if executable is None: expected = fsencode(get_executable()) else: expected = executable.encode('utf-8') expected = b'#!' + expected + b' -E' self.assertIn(expected, data)
def test_custom_executable(self): fn = os.path.join(HERE, "dummy-0.1-py27-none-any.whl") for executable in "mypython", None: dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {"prefix": dstdir} for key in ("purelib", "platlib", "headers", "scripts", "data"): paths[key] = os.path.join(dstdir, key) maker = ScriptMaker(None, None) maker.variants = set([""]) maker.executable = executable w.install(paths, maker) # On Windows there will be an exe file, and on POSIX a text file. # The test is structured to not care. p = paths["scripts"] # there should be just one file in the directory - dummy.py/dummy.exe p = os.path.join(p, os.listdir(p)[0]) with open(p, "rb") as f: data = f.read() if executable is None: expected = fsencode(get_executable()) else: expected = executable.encode("utf-8") expected = b"#!" + expected + b" -E" if not sysconfig.is_python_build(): self.assertIn(expected, data)
def test_version_incompatibility(self): class Warner(object): def __call__(self, wheel_version, file_version): self.wheel_version = wheel_version self.file_version = file_version fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) warner = Warner() maker = ScriptMaker(None, None) w.install(paths, maker, warner=warner) self.assertEqual(warner.wheel_version, w.wheel_version) self.assertEqual(warner.file_version, (2, 0)) # Now set the wheel's instance to the higher value and ensure # warner isn't called warner = Warner() w.wheel_version = (2, 0) w.install(paths, maker, warner=warner) self.assertFalse(hasattr(warner, 'wheel_version')) self.assertFalse(hasattr(warner, 'file_version'))
def test_custom_executable(self): fn = os.path.join(HERE, 'dummy-0.1-py27-none-any.whl') for executable in 'mypython', None: dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) w = Wheel(fn) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) maker = ScriptMaker(None, None) maker.variants = set(['']) maker.executable = executable w.install(paths, maker) # On Windows there will be an exe file, and on POSIX a text file. # The test is structured to not care. p = paths['scripts'] # there should be just one file in the directory - dummy.py/dummy.exe p = os.path.join(p, os.listdir(p)[0]) with open(p, 'rb') as f: data = f.read() if executable is None: expected = fsencode(get_executable()) else: expected = executable.encode('utf-8') expected = b'#!' + expected + b' -E' if not sysconfig.is_python_build(): self.assertIn(expected, data)
def install_wheel(self, wheel: Wheel) -> None: paths = self.environment.get_paths() scripts = distlib.scripts.ScriptMaker(None, None) scripts.executable = self.environment.python_executable scripts.script_template = scripts.script_template.replace( "import sys", "import sys\nsys.path.insert(0, {!r})".format(paths["platlib"]), ) wheel.install(paths, scripts)
def install_wheel(self, wheel: Wheel) -> None: paths = self.environment.get_paths() maker = distlib.scripts.ScriptMaker(None, None) maker.variants = set(("",)) enquoted_executable = distlib.scripts.enquote_executable( self.environment.interpreter.executable ) maker.executable = enquoted_executable wheel.install(paths, maker)
def do_build_and_install(self, dist): srcdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, srcdir) dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) paths = install_dist(dist, srcdir) paths['prefix'] = srcdir w = Wheel() w.name = paths.pop('name') w.version = paths.pop('version') w.dirname = srcdir pathname = w.build(paths) self.assertTrue(os.path.exists(pathname)) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) w = Wheel(pathname) executable = os.path.join(paths['scripts'], 'python') dist = w.install(paths, executable=executable) self.assertIsNotNone(dist) self.assertEqual(dist.name, w.name) self.assertEqual(dist.version, w.version) os.remove(pathname) sm = Manifest(srcdir) sm.findall() sfiles = set([os.path.relpath(p, srcdir) for p in sm.allfiles]) dm = Manifest(dstdir) dm.findall() dfiles = set([os.path.relpath(p, dstdir) for p in dm.allfiles]) omitted = sfiles - dfiles omitted = omitted.pop() endings = os.path.join('.dist-info', 'WHEEL'), '.pyc', '.pyo' self.assertTrue(omitted.endswith(endings))
def install_wheels(wheels_folder, install_folder): logging.getLogger('distlib').setLevel(logging.ERROR) if not os.path.exists(install_folder): os.makedirs(install_folder) from distlib.wheel import Wheel from distlib.scripts import ScriptMaker paths = { 'prefix': '', 'purelib': install_folder, 'platlib': install_folder, 'scripts': '', 'headers': '', 'data': ''} files = os.listdir(wheels_folder) for f in [os.path.join(wheels_folder, f) for f in files]: wheel = Wheel(f) wheel.install(paths, ScriptMaker(None, None), lib_only=True)
def install_wheels(wheels_folder, install_folder): logging.getLogger('distlib').setLevel(logging.ERROR) if not os.path.exists(install_folder): os.makedirs(install_folder) from distlib.wheel import Wheel from distlib.scripts import ScriptMaker paths = { 'prefix': '', 'purelib': install_folder, 'platlib': install_folder, 'scripts': '', 'headers': '', 'data': ''} files = os.listdir(wheels_folder) for f in [os.path.join(wheels_folder, f) for f in files]: wheel = Wheel(f) wheel.install(paths, ScriptMaker(None, None), lib_only=True)
def locate(simple_url, pkg, dest, work): locator = SimpleScrapingLocator(simple_url) dist = locator.locate(pkg) url = list(dist.download_urls)[0] download = request.urlopen(url) fname = url.split('/')[-1] with open(os.path.join(work, fname), 'wb') as f: f.write(download.read()) wheel = Wheel(os.path.join(work, fname)) print(wheel.name) paths = { 'purelib': dest, 'platlib': dest, 'prefix': dest, 'headers': dest, 'scripts': dest, 'data': dest, } maker = ScriptMaker(None, None) wheel.install(paths, maker)
def __install_wheel( self, filepath: str, force: bool, upgrade: bool, options: dict, ) -> InstalledDistribution: '''Install wheel to selected paths.''' wheel = Wheel(filepath) try: wheel.verify() return wheel.install( paths=self.distribution_path.paths, maker=ScriptMaker(None, None), # bytecode_hashed_invalidation=True ) except DistlibException: print('wheel did not pass validation')
def do_build_and_install(self, dist): srcdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, srcdir) dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) paths = install_dist(dist, srcdir) paths['prefix'] = srcdir w = Wheel() w.name = paths.pop('name') w.version = paths.pop('version') w.dirname = srcdir pathname = w.build(paths) self.assertTrue(os.path.exists(pathname)) paths = {'prefix': dstdir} for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): paths[key] = os.path.join(dstdir, key) w = Wheel(pathname) maker = ScriptMaker(None, None, add_launchers=False) maker.executable = os.path.join(paths['scripts'], 'python') dist = w.install(paths, maker) self.assertIsNotNone(dist) self.assertEqual(dist.name, w.name) self.assertEqual(dist.version, w.version) shared = dist.shared_locations self.assertTrue(shared) os.remove(pathname) sm = Manifest(srcdir) sm.findall() sfiles = set([os.path.relpath(p, srcdir) for p in sm.allfiles]) dm = Manifest(dstdir) dm.findall() dfiles = set([os.path.relpath(p, dstdir) for p in dm.allfiles]) omitted = sfiles - dfiles omitted = omitted.pop() endings = os.path.join('.dist-info', 'WHEEL'), '.pyc', '.pyo' self.assertTrue(omitted.endswith(endings))
def do_build_and_install(self, dist): srcdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, srcdir) dstdir = tempfile.mkdtemp() self.addCleanup(shutil.rmtree, dstdir) paths = install_dist(dist, srcdir) paths["prefix"] = srcdir w = Wheel() w.name = paths.pop("name") w.version = paths.pop("version") w.dirname = srcdir pathname = w.build(paths) self.assertTrue(os.path.exists(pathname)) paths = {"prefix": dstdir} for key in ("purelib", "platlib", "headers", "scripts", "data"): paths[key] = os.path.join(dstdir, key) w = Wheel(pathname) maker = ScriptMaker(None, None, add_launchers=False) maker.executable = os.path.join(paths["scripts"], "python") dist = w.install(paths, maker) self.assertIsNotNone(dist) self.assertEqual(dist.name, w.name) self.assertEqual(dist.version, w.version) shared = dist.shared_locations self.assertTrue(shared) os.remove(pathname) sm = Manifest(srcdir) sm.findall() sfiles = set([os.path.relpath(p, srcdir) for p in sm.allfiles]) dm = Manifest(dstdir) dm.findall() dfiles = set([os.path.relpath(p, dstdir) for p in dm.allfiles]) omitted = sfiles - dfiles omitted = omitted.pop() endings = os.path.join(".dist-info", "WHEEL"), ".pyc", ".pyo" self.assertTrue(omitted.endswith(endings))
def install_wheel(self, wheel: Wheel) -> None: paths = self.environment.get_paths() maker = distlib.scripts.ScriptMaker(None, None) maker.executable = self.environment.python_executable wheel.install(paths, maker)
def handle(self, requester, data): name = data['requirement'].name wheel = Wheel(data['wheel']) wheel.install(get_distribution_paths(name)) return data
def _install_wheels(need, system): # TODO: if a package is being updated, it should be installed in # the same location as before # Find all packages that should be deleted all = dict([ (d.name, d) for d in installed_core() | installed_tools() | installed_toolboxes() ]) from distlib.database import make_graph import itertools graph = make_graph(itertools.chain(all.values(), need)) l = need[:] # what we started with ordered = [] # ordered by least dependency depend = {} # dependency relationship cache while l: for d in l: for d2 in l: if d2 is d: continue try: dep = depend[(d, d2)] except KeyError: dep = _depends_on(graph, d, d2) depend[(d, d2)] = dep if dep: break else: ordered.append(d) l.remove(d) break else: # This can only happen if there is circular dependencies # in which case we just process the distributions in # given order since its no worse than anything else ordered.extend(l) break remove_list = [] check = set() for d in ordered: if d in remove_list: continue try: rd = all[d.name] except KeyError: pass else: remove_list.append(rd) al = graph.adjacency_list[rd] if al: check.update([ sd for sd, l in al ]) # Repeatedly go through the list of distributions to see whether # they can be removed. It must be iterative. Suppose A and B need # to be removed; C depends on A; D depends on B and C; if we check D # first, it will not be removable since C is not marked for removal # yet; but a second pass will show that D is removable. Iteration # ends when no new packages are marked as removable. while check: any_deletion = False new_check = set() for d in check: for pd in graph.reverse_list[d]: if pd not in remove_list: new_check.add(d) break else: any_deletion = True remove_list.append(d) for sd, l in graph.adjacency_list[d]: if sd not in remove_list and sd not in check: new_check.add(sd) if not any_deletion: break check = new_check removed_location = {} for d in remove_list: removed_location[d.name] = _remove_distribution(d) dl = download_location() default_paths = _install_make_paths(system) from distlib.scripts import ScriptMaker maker = ScriptMaker(None, None) import os.path try: from urllib.request import urlretrieve, URLError except ImportError: from urllib import urlretrieve, URLError from distlib.wheel import Wheel from distlib import DistlibException for d in need: try: old_location = removed_location[d.name] except KeyError: paths = default_paths else: paths = _install_make_paths(system, old_location) url = d.source_url filename = url.split('/')[-1] dloc = os.path.join(dl, filename) if not os.path.isfile(dloc): try: filename, headers = urlretrieve(url, dloc) except URLError as e: show("Warning: cannot fetch %s: %s" % (url, str(e))) continue w = Wheel(dloc) try: w.verify() except DistlibExecption as e: show("Warning: cannot verify %s: %s" % (d.name, str(e))) continue show("installing %s (%s)" % (w.name, w.version)) w.install(paths, maker)
def handle(self, requester, data): name = parse_requirement(data['requirement']).name wheel = Wheel(data['wheel']) wheel.install(get_distribution_paths(name)) return data