def test_marker_evaluation_with_extras_loop(self): ad = pkg_resources.Environment([]) ws = WorkingSet([]) # Metadata needs to be native strings due to cStringIO behaviour in # 2.6, so use str(). a = Distribution.from_filename( "/foo_dir/a-0.2.dist-info", metadata=Metadata(("METADATA", str("Requires-Dist: c[a]"))) ) b = Distribution.from_filename( "/foo_dir/b-0.3.dist-info", metadata=Metadata(("METADATA", str("Requires-Dist: c[b]"))) ) c = Distribution.from_filename( "/foo_dir/c-1.0.dist-info", metadata=Metadata(("METADATA", str("Provides-Extra: a\n" "Requires-Dist: b;extra=='a'\n" "Provides-Extra: b\n" "Requires-Dist: foo;extra=='b'"))) ) foo = Distribution.from_filename("/foo_dir/foo-0.1.dist-info") for dist in (a, b, c, foo): ad.add(dist) res = list(ws.resolve(parse_requirements("a"), ad)) assert res == [a, c, b, foo]
def run(self): if sys.platform == 'win32': raise Exception("Symlinking scripts doesn't work with Windows") self.run_command("egg_info") if self.distribution.scripts: # run first to set up self.outfiles orig.install_scripts.run(self) else: self.outfiles = [] if self.no_ep: # don't install entry point scripts into .egg file! return # build distribution object ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), ei_cmd.egg_name, ei_cmd.egg_version, ) # fetch entry points and create symlinks to the targets for type_ in 'console', 'gui': group = type_ + '_scripts' for name, ep in dist.get_entry_map(group).items(): log.info('install_symlinked_scripts: %s: %s', group, ep) if os.sep in name: raise ValueError("Path separators not allowed in script names") self.symlink_script(name, ep)
def test_conflict_registration(self): # create an empty working set for a clean-slate test. cwd = utils.mkdtemp(self) mock_ws = WorkingSet([]) registry = ArtifactRegistry('calmjs.artifacts', _working_set=mock_ws) # using named case for case sensitivity test. st = join(cwd, 'calmjs_artifacts', 'Simple.js') dist_ = Distribution(cwd, project_name='pkg', version='1.0') dist_.egg_info = cwd # just lazy s1 = EntryPoint.parse('Simple.js = dummy_builder:builder1') s1.dist = dist_ s2 = EntryPoint.parse('Simple.js = dummy_builder:builder2') s2.dist = dist_ with pretty_logging(stream=mocks.StringIO()) as stream: registry.register_entry_point(s1) # normal registry usage shouldn't be able to do this. registry.register_entry_point(s2) log = stream.getvalue() self.assertIn( "entry point 'Simple.js = dummy_builder:builder2' from package " "'pkg 1.0' resolves to the path '%s' which was already " "registered to entry point 'Simple.js = dummy_builder:builder1'; " "conflicting entry point registration will be ignored." % st, log )
def test_normcase_registration(self): # create an empty working set for a clean-slate test. cwd = utils.mkdtemp(self) mock_ws = WorkingSet([]) dist_ = Distribution(cwd, project_name='pkg', version='1.0') dist_.egg_info = cwd # just lazy registry = ArtifactRegistry('calmjs.artifacts', _working_set=mock_ws) # case sensitive test; have to patch the normcase at artifact # module with the nt version from ntpath import normcase as nt_normcase utils.stub_item_attr_value(self, artifact, 'normcase', nt_normcase) # using named case for case sensitivity test. c1 = EntryPoint.parse('case.js = dummy_builder:builder1') c1.dist = dist_ c2 = EntryPoint.parse('Case.js = dummy_builder:builder2') c2.dist = dist_ # use the error one ct = join(cwd, 'calmjs_artifacts', 'Case.js') with pretty_logging(stream=mocks.StringIO()) as stream: registry.register_entry_point(c1) registry.register_entry_point(c2) log = stream.getvalue() self.assertIn( "entry point 'Case.js = dummy_builder:builder2' from package " "'pkg 1.0' resolves to the path '%s' which was already " "registered to entry point 'case.js = dummy_builder:builder1'; " "conflicting entry point registration will be ignored." % ct, log ) self.assertIn( "the file mapping error is caused by this platform's case-" "insensitive filename", log )
def create_dist(name, version, requires={}, setup_requires={}, extras_require={}, tests_require=[], extra_egg_info=None, location=None): if location is None: location = name if extra_egg_info is None: extra_egg_info = {} metadata = {} metadata.update(extra_egg_info) requires = _req_lines_from_dict(requires) metadata["install_requires"] = requires if extras_require: extras_list = "\n".join("[%s]\n%s\n" % (n, "\n".join(extras)) for n, extras in ((k, [v] if isinstance(v, str_type) else v) for k, v in extras_require.items())) requires = requires + "\n" + extras_list metadata['requires.txt'] = requires.encode('utf-8') metadata["setup_requires"] = _create_requires_list(setup_requires) metadata["setup_requires"] = metadata["setup_requires"].splitlines() metadata = _DictMetaProvider(metadata, name=name) d = Distribution(project_name=name, version=version, metadata=metadata, location=location) d.tests_require = tests_require return d
def test_resolve_conflicts_with_prior(self): """ A ContextualVersionConflict should be raised when a requirement conflicts with a prior requirement for a different package. """ # Create installation where Foo depends on Baz 1.0 and Bar depends on # Baz 2.0. ws = WorkingSet([]) md = Metadata(('depends.txt', "Baz==1.0")) Foo = Distribution.from_filename("/foo_dir/Foo-1.0.egg", metadata=md) ws.add(Foo) md = Metadata(('depends.txt', "Baz==2.0")) Bar = Distribution.from_filename("/foo_dir/Bar-1.0.egg", metadata=md) ws.add(Bar) Baz = Distribution.from_filename("/foo_dir/Baz-1.0.egg") ws.add(Baz) Baz = Distribution.from_filename("/foo_dir/Baz-2.0.egg") ws.add(Baz) with pytest.raises(VersionConflict) as vc: ws.resolve(parse_requirements("Foo\nBar\n")) msg = "Baz 1.0 is installed but Baz==2.0 is required by " msg += repr(set(['Bar'])) assert vc.value.report() == msg
def testBasicContains(self): r = Requirement("Twisted", [(">=", "1.2")], ()) foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg") twist11 = Distribution.from_filename("Twisted-1.1.egg") twist12 = Distribution.from_filename("Twisted-1.2.egg") assert parse_version("1.2") in r assert parse_version("1.1") not in r assert "1.2" in r assert "1.1" not in r assert foo_dist not in r assert twist11 not in r assert twist12 in r
def testBasicContains(self): r = Requirement("Twisted>=1.2") foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg") twist11 = Distribution.from_filename("Twisted-1.1.egg") twist12 = Distribution.from_filename("Twisted-1.2.egg") assert parse_version('1.2') in r assert parse_version('1.1') not in r assert '1.2' in r assert '1.1' not in r assert foo_dist not in r assert twist11 not in r assert twist12 in r
def testBasicContains(self): r = Requirement("Twisted", [('>=','1.2')], ()) foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg") twist11 = Distribution.from_filename("Twisted-1.1.egg") twist12 = Distribution.from_filename("Twisted-1.2.egg") self.assertTrue(parse_version('1.2') in r) self.assertTrue(parse_version('1.1') not in r) self.assertTrue('1.2' in r) self.assertTrue('1.1' not in r) self.assertTrue(foo_dist not in r) self.assertTrue(twist11 not in r) self.assertTrue(twist12 in r)
def test_marker_evaluation_with_extras_normlized(self): """Extras are also evaluated as markers at resolution time.""" ad = pkg_resources.Environment([]) ws = WorkingSet([]) Foo = Distribution.from_filename( "/foo_dir/Foo-1.2.dist-info", metadata=Metadata(("METADATA", "Provides-Extra: baz-lightyear\n" "Requires-Dist: quux; extra=='baz-lightyear'")) ) ad.add(Foo) assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo] quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info") ad.add(quux) res = list(ws.resolve(parse_requirements("Foo[baz-lightyear]"), ad)) assert res == [Foo, quux]
def test_environment_marker_evaluation_positive(self): ad = pkg_resources.Environment([]) ws = WorkingSet([]) Foo = Distribution.from_filename("/foo_dir/Foo-1.2.dist-info") ad.add(Foo) res = ws.resolve(parse_requirements("Foo;python_version>='2'"), ad) assert list(res) == [Foo]
def distros_for_location(location, basename, metadata=None): """Yield egg or source distribution objects based on basename""" if basename.endswith('.egg.zip'): basename = basename[:-4] # strip the .zip if basename.endswith('.egg') and '-' in basename: # only one, unambiguous interpretation return [Distribution.from_location(location, basename, metadata)] if basename.endswith('.whl') and '-' in basename: wheel = Wheel(basename) if not wheel.is_compatible(): return [] return [Distribution( location=location, project_name=wheel.project_name, version=wheel.version, # Increase priority over eggs. precedence=EGG_DIST + 1, )] if basename.endswith('.exe'): win_base, py_ver, platform = parse_bdist_wininst(basename) if win_base is not None: return interpret_distro_name( location, win_base, metadata, py_ver, BINARY_DIST, platform ) # Try source distro extensions (.zip, .tgz, etc.) # for ext in EXTENSIONS: if basename.endswith(ext): basename = basename[:-len(ext)] return interpret_distro_name(location, basename, metadata) return [] # no extension matched
def local_distribution(self): if self._local_dist is None: ensure_directory(os.path.join(self.tmpdir, "dummy")) info("Fetching %s from %s..." % (str(self.distribution), self.location)) dist = self.repository.environment.fetch_distribution(self.requirement, self.tmpdir, source=self.source, develop_ok=self.develop) location = dist.location distros = list(find_distributions(location)) if distros: self._local_dist = distros[0] elif os.path.isfile(location) and os.path.splitext(location) != \ ".py": # try to unpack the file unpack_dir = os.path.join(self.tmpdir, "unpack") info("Unpacking to %s..." % unpack_dir) unpack_archive(location, unpack_dir) distros = list(find_distributions(unpack_dir)) if distros: self._local_dist = distros[0] else: for path in glob(os.path.join(unpack_dir, "*")): distros = list(find_distributions(path)) if distros: self._local_dist = distros[0] break else: self._local_dist = Distribution.from_filename(location) return self._local_dist
def dist_from_egg(egg_path): if os.path.isdir(egg_path): metadata = PathMetadata(egg_path, os.path.join(egg_path, 'EGG-INFO')) else: # Assume it's a file or an internal egg metadata = EggMetadata(zipimporter(egg_path)) return Distribution.from_filename(egg_path, metadata=metadata)
def _init_environment(self): dist_folders = map(lambda d: os.path.join(os.getcwd(), self.mod_folder, d), os.listdir(self.mod_folder)) dist_folders = filter(lambda f: os.path.exists(os.path.join(f, "EGG-INFO")), dist_folders) dists = map(lambda f: Distribution.from_filename(f) , dist_folders) # self.pkg_env = Environment() for dist in dists: self.pkg_env.add(dist)
def egg_dist(egg_path): metadata_func = \ egg_path_metadata if os.path.isdir(egg_path) else egg_zip_metadata metadata = metadata_func(egg_path) if metadata is not None: return Distribution.from_filename(egg_path, metadata=metadata)
def PythonEgg(glob, name=None): """Refers to pre-built Python eggs in the file system. (To instead fetch eggs in a ``pip``/``easy_install`` way, use ``python_requirement``) E.g., ``egg(name='foo', glob='foo-0.1-py2.6.egg')`` would pick up the file ``foo-0.1-py2.6.egg`` from the ``BUILD`` file's directory; targets could depend on it by name ``foo``. :param string glob: File glob pattern. :param string name: Target name; by default uses the egg's project name. """ # TODO(John Sirois): Rationalize with globs handling in ParseContext eggs = fsglob(ParseContext.path(glob)) requirements = set() for egg in eggs: if os.path.isdir(egg): metadata = PathMetadata(egg, os.path.join(egg, 'EGG-INFO')) else: metadata = EggMetadata(zipimporter(egg)) dist = Distribution.from_filename(egg, metadata=metadata) requirements.add(dist.as_requirement()) if len(requirements) > 1: raise ValueError('Got multiple egg versions! => %s' % requirements) return PythonRequirement(str(requirements.pop()), name=name)
def test_marker_evaluation_with_multiple_extras(self): ad = pkg_resources.Environment([]) ws = WorkingSet([]) Foo = Distribution.from_filename( "/foo_dir/Foo-1.2.dist-info", metadata=Metadata(("METADATA", "Provides-Extra: baz\n" "Requires-Dist: quux; extra=='baz'\n" "Provides-Extra: bar\n" "Requires-Dist: fred; extra=='bar'\n")) ) ad.add(Foo) quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info") ad.add(quux) fred = Distribution.from_filename("/foo_dir/fred-0.1.dist-info") ad.add(fred) res = list(ws.resolve(parse_requirements("Foo[baz,bar]"), ad)) assert sorted(res) == [fred, quux, Foo]
def test_marker_evaluation_with_extras(self): """Extras are also evaluated as markers at resolution time.""" ad = pkg_resources.Environment([]) ws = WorkingSet([]) # Metadata needs to be native strings due to cStringIO behaviour in # 2.6, so use str(). Foo = Distribution.from_filename( "/foo_dir/Foo-1.2.dist-info", metadata=Metadata(("METADATA", str("Provides-Extra: baz\n" "Requires-Dist: quux; extra=='baz'"))) ) ad.add(Foo) assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo] quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info") ad.add(quux) res = list(ws.resolve(parse_requirements("Foo[baz]"), ad)) assert res == [Foo, quux]
def add_egg(self, egg): """ helper for add_distribution """ metadata = EggMetadata(zipimporter(egg)) dist = Distribution.from_filename(egg, metadata) self.add_distribution(dist) self.add_requirement(dist.as_requirement(), dynamic=False, repo=None)
def testResolve(self): ad = pkg_resources.Environment([]) ws = WorkingSet([]) # Resolving no requirements -> nothing to install assert list(ws.resolve([], ad)) == [] # Request something not in the collection -> DistributionNotFound with pytest.raises(pkg_resources.DistributionNotFound): ws.resolve(parse_requirements("Foo"), ad) Foo = Distribution.from_filename( "/foo_dir/Foo-1.2.egg", metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0")) ) ad.add(Foo) ad.add(Distribution.from_filename("Foo-0.9.egg")) # Request thing(s) that are available -> list to activate for i in range(3): targets = list(ws.resolve(parse_requirements("Foo"), ad)) assert targets == [Foo] list(map(ws.add, targets)) with pytest.raises(VersionConflict): ws.resolve(parse_requirements("Foo==0.9"), ad) ws = WorkingSet([]) # reset # Request an extra that causes an unresolved dependency for "Baz" with pytest.raises(pkg_resources.DistributionNotFound): ws.resolve(parse_requirements("Foo[bar]"), ad) Baz = Distribution.from_filename( "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo")) ) ad.add(Baz) # Activation list now includes resolved dependency assert ( list(ws.resolve(parse_requirements("Foo[bar]"), ad)) == [Foo, Baz] ) # Requests for conflicting versions produce VersionConflict with pytest.raises(VersionConflict) as vc: ws.resolve(parse_requirements("Foo==1.2\nFoo!=1.2"), ad) msg = 'Foo 0.9 is installed but Foo==1.2 is required' assert vc.value.report() == msg
def _convert_metadata(zf, destination_eggdir, dist_info, egg_info): def get_metadata(name): with zf.open(posixpath.join(dist_info, name)) as fp: value = fp.read().decode('utf-8') if PY3 else fp.read() return email.parser.Parser().parsestr(value) wheel_metadata = get_metadata('WHEEL') # Check wheel format version is supported. wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) wheel_v1 = ( parse_version('1.0') <= wheel_version < parse_version('2.0dev0') ) if not wheel_v1: raise ValueError( 'unsupported wheel format version: %s' % wheel_version) # Extract to target directory. os.mkdir(destination_eggdir) zf.extractall(destination_eggdir) # Convert metadata. dist_info = os.path.join(destination_eggdir, dist_info) dist = Distribution.from_location( destination_eggdir, dist_info, metadata=PathMetadata(destination_eggdir, dist_info), ) # Note: Evaluate and strip markers now, # as it's difficult to convert back from the syntax: # foobar; "linux" in sys_platform and extra == 'test' def raw_req(req): req.marker = None return str(req) install_requires = list(sorted(map(raw_req, dist.requires()))) extras_require = { extra: sorted( req for req in map(raw_req, dist.requires((extra,))) if req not in install_requires ) for extra in dist.extras } os.rename(dist_info, egg_info) os.rename( os.path.join(egg_info, 'METADATA'), os.path.join(egg_info, 'PKG-INFO'), ) setup_dist = SetuptoolsDistribution( attrs=dict( install_requires=install_requires, extras_require=extras_require, ), ) write_requirements( setup_dist.get_command_obj('egg_info'), None, os.path.join(egg_info, 'requires.txt'), )
def get_egg_distribution_links(self, package, version=None, py_version=sys.version_info, dev=False, strict=False): """ Return links to available egg distributions. Parameters ---------- package : `str` name of the package version : `str` or `bool` version of the package. Optional, if not provided links for all available versions of the package will be returned. py_version : `str` or `distutils.version.Version` target Python version for distributions. Only those distributions which are compatible with the version of Python will be returned. Defaults to the Python version of the current interpreter. If None is provided will return distributions for all Python platforms. dev: `bool` If set, will only return dev versions. Otherwise, return only released versions. strict: `bool` If set, matches dev versions strictly. Eg: 0.0.dev OK, 2.33.dev3 -not OK. Returns ------- dists : `dict` a map of `str`->`pkg_resources.Distribution` (distribution URL -> distribution object) """ fn = ((util.is_strict_dev_version if strict else util.is_dev_version) if dev else (lambda v: not util.is_dev_version(v))) py_version = py_version and util.short_version(py_version, max_parts=2) dists = {} for l in self.get_links(package): if not l.endswith(".egg"): continue d = Distribution.from_filename(l.rsplit("/", 1)[-1]) if py_version and d.py_version != py_version: continue if not fn(d.version): continue if version and d.version != version: continue dists[l] = d return dists
def run(self): for egg_file in self.egg_files: distribution = self.distribution self.egg_file = egg_file self.announce("Reading package metadata from the egg file: %s" % self.egg_file, level=INFO) distribution.metadata = manage_egg.get_egg_metadata(self.egg_file) self.dist = Distribution.from_filename(self.egg_file) distribution.dist_files = [("bdist_egg", self.dist.py_version, self.egg_file)] upload.run(self)
def testResolve(self): ad = pkg_resources.Environment([]) ws = WorkingSet([]) # Resolving no requirements -> nothing to install self.assertEqual(list(ws.resolve([],ad)), []) # Request something not in the collection -> DistributionNotFound self.assertRaises( pkg_resources.DistributionNotFound, ws.resolve, parse_requirements("Foo"), ad ) Foo = Distribution.from_filename( "/foo_dir/Foo-1.2.egg", metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0")) ) ad.add(Foo) ad.add(Distribution.from_filename("Foo-0.9.egg")) # Request thing(s) that are available -> list to activate for i in range(3): targets = list(ws.resolve(parse_requirements("Foo"), ad)) self.assertEqual(targets, [Foo]) list(map(ws.add,targets)) self.assertRaises(VersionConflict, ws.resolve, parse_requirements("Foo==0.9"), ad) ws = WorkingSet([]) # reset # Request an extra that causes an unresolved dependency for "Baz" self.assertRaises( pkg_resources.DistributionNotFound, ws.resolve,parse_requirements("Foo[bar]"), ad ) Baz = Distribution.from_filename( "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo")) ) ad.add(Baz) # Activation list now includes resolved dependency self.assertEqual( list(ws.resolve(parse_requirements("Foo[bar]"), ad)), [Foo,Baz] ) # Requests for conflicting versions produce VersionConflict self.assertRaises(VersionConflict, ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
def onlyInImage(self): ''' Returns a set of packs to fix (in the image , but not in the database). ex. {'ZenPacks.zenoss.ApacheMonitor', 'ZenPacks.zenoss.ZenJMX'} ''' shippedPacks = self.getPacksPacks() genericShippedPacks = [ Distribution.from_filename(pack).project_name for pack in shippedPacks ] databasePacks = self.dmd.ZenPackManager.packs.objectIds() installedPacks = [ p.name for p in iter_entry_points('zenoss.zenpacks') ] packsInImageNotInDB = (set(installedPacks) | set(genericShippedPacks)) - set(databasePacks) packsToFix = packsInImageNotInDB & set(installedPacks) return packsToFix
def __init__( self, location=None, metadata=None, project_name=None, version=None, py_version=PY_MAJOR, platform=None, precedence=EGG_DIST, ep_yaml=None, ): if ep_yaml is None: ep_yaml = {} self._ep_map = {} for group, impl in ep_yaml.items(): i = {} for im, loc in impl.items(): ep = EntryPoint.parse("%s=%s" % (im, loc), dist=self) i[ep.name] = ep self._ep_map[group] = i Distribution.__init__(self, location, metadata, project_name, version, py_version, platform, precedence)
def test_find_conflicting(self): ws = WorkingSet([]) Foo = Distribution.from_filename("/foo_dir/Foo-1.2.egg") ws.add(Foo) # create a requirement that conflicts with Foo 1.2 req = next(parse_requirements("Foo<1.2")) with pytest.raises(VersionConflict) as vc: ws.find(req) msg = 'Foo 1.2 is installed but Foo<1.2 is required' assert vc.value.report() == msg
def _run_tests(self): old_path = sys.path[:] ei_cmd = self.get_finalized_command("egg_info") path_item = normalize_path(ei_cmd.egg_base) metadata = PathMetadata( path_item, normalize_path(ei_cmd.egg_info) ) dist = Distribution(path_item, metadata, project_name=ei_cmd.egg_name) working_set.add(dist) require(str(dist.as_requirement())) loader_ep = EntryPoint.parse("x=" + self.test_loader) loader_class = loader_ep.load(require=False) try: import unittest unittest.main( None, None, [unittest.__file__] + self.test_args, testRunner=XMLTestRunner(stream=sys.stdout, xml_stream=self.xml_output_file), testLoader=loader_class() ) except SystemExit, e: return e.code
def distribution_from_path(cls, location, location_base=None): """Returns a Distribution given a location. If the distribution name should be based off a different egg name than described by the location, supply location_base as an alternate name, e.g. DistributionHelper.distribution_from_path('/path/to/wrong_package_name-3.2.1', 'right_package_name-1.2.3.egg') """ location_base = location_base or os.path.basename(location) if os.path.isdir(location): metadata = PathMetadata(location, os.path.join(location, 'EGG-INFO')) else: from zipimport import zipimporter metadata = EggMetadata(zipimporter(location)) return Distribution.from_location(location, location_base, metadata=metadata)
def finalize_options(self): ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info") self.egg_info = ei_cmd.egg_info if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'egg') if self.plat_name is None: self.plat_name = get_build_platform() self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) if self.egg_output is None: # Compute filename of the output egg basename = Distribution( None, None, ei_cmd.egg_name, ei_cmd.egg_version, get_python_version(), self.distribution.has_ext_modules() and self.plat_name).egg_name() self.egg_output = os.path.join(self.dist_dir, basename + '.egg')
def run(self): self.run_command("egg_info") if self.distribution.scripts: _install_scripts.run(self) # run first to set up self.outfiles else: self.outfiles = [] if self.no_ep: # don't install entry point scripts into .egg file! return ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') executable = getattr(bs_cmd, 'executable', sys_executable) is_wininst = getattr(self.get_finalized_command("bdist_wininst"), '_is_running', False) for args in get_script_args(dist, executable, is_wininst): self.write_script(*args)
def _resolve_requirements(provider: str, distribution: pkg_resources.Distribution) -> bool: try: requirements: List[pkg_resources.Requirement] = distribution.requires( extras=(provider, )) except pkg_resources.UnknownExtra: # No extra for this provider return True else: # Extra is defined try: for requirement in requirements: if hasattr(requirement, "name"): pkg_resources.get_distribution( requirement.name) # type: ignore else: pkg_resources.get_distribution(requirement) except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict): # At least one extra requirement is not fulfilled return False return True
def test_registry_autoreload_base_support(self): # This is just to test the setup of the relevant entry correctly # but does not actually deal with the more dynamic functionality # that molds offer. setup_tmp_module(self) entry_points = ['tmp = tmp:mold'] working_set = mocks.WorkingSet({'nunja.tmpl': entry_points}, dist=Distribution( project_name='nunjatesting', version='0.0')) registry = JinjaTemplateRegistry.create(_working_set=working_set, auto_reload=False) self.assertFalse(registry.tracked_entry_points) with self.assertRaises(KeyError): registry.lookup_path('tmp/itemlist') registry = JinjaTemplateRegistry.create(_working_set=working_set, auto_reload=True) self.assertEqual(str(registry.tracked_entry_points['tmp']), entry_points[0])
def test_list_one_installed(environment: Environment): env = Environment(search_path=[]) environment.return_value = env metadata = """Metadata-Version: 2.1 Name: chaostoolkit-some-stuff Version: 0.1.0 Summary: Chaos Toolkit some package Home-page: http://chaostoolkit.org Author: chaostoolkit Team Author-email: [email protected] License: Apache License 2.0 """ env.add( Distribution(project_name="chaostoolkit-some-stuff", version="0.1.0", metadata=InMemoryMetadata({"PKG-INFO": metadata}))) extensions = list_extensions() assert len(extensions) == 1 ext = extensions[0] assert ext.name == "chaostoolkit-some-stuff" assert ext.version == "0.1.0"
def run(self): import setuptools.command.easy_install as ei self.run_command("egg_info") if self.distribution.scripts: orig.install_scripts.run(self) # run first to set up self.outfiles else: self.outfiles = [] if self.no_ep: # don't install entry point scripts into .egg file! return ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = (self.get_finalized_command('build_scripts', create=False) or self.get_finalized_command('install')) exec_param = getattr(bs_cmd, 'executable', None) bw_cmd = self.get_finalized_command("bdist_wininst") is_wininst = getattr(bw_cmd, '_is_running', False) writer = ei.ScriptWriter if is_wininst: exec_param = "python.exe" writer = ei.WindowsScriptWriter if exec_param == sys.executable: # In case the path to the Python executable contains a space, wrap # it so it's not split up. exec_param = [exec_param] # resolve the writer to the environment writer = writer.best() cmd = writer.command_spec_class.best().from_param(exec_param) for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args)
def _venv_match(self, installed, requirements): """Return True if what is installed satisfies the requirements. This method has multiple exit-points, but only for False (because if *anything* is not satisified, the venv is no good). Only after all was checked, and it didn't exit, the venv is ok so return True. """ if not requirements: # special case for no requirements, where we can't actually # check anything: the venv is useful if nothing installed too return not bool(installed) useful_inst = set() for repo, req_deps in requirements.items(): if repo not in installed: # the venv doesn't even have the repo return False inst_deps = { Distribution(project_name=dep, version=ver) for (dep, ver) in installed[repo].items() } for req in req_deps: for inst in inst_deps: if inst in req: useful_inst.add(inst) break else: # nothing installed satisfied that requirement return False # assure *all* that is installed is useful for the requirements if useful_inst != inst_deps: return False # it did it through! return True
def finalize_options(self): ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: raise DistutilsError( "Please rename %r to %r before using 'develop'" % (ei.egg_info, ei.broken_egg_info)) self.args = [ei.egg_name] easy_install.finalize_options(self) self.egg_link = os.path.join(self.install_dir, ei.egg_name + '.egg-link') self.egg_base = ei.egg_base if self.egg_path is None: self.egg_path = os.path.abspath(ei.egg_base) target = normalize_path(self.egg_base) if normalize_path(os.path.join(self.install_dir, self.egg_path)) != target: raise DistutilsOptionError( "--egg-path must be a relative path from the install" " directory to " + target) # Make a distribution for the package's source self.dist = Distribution(target, PathMetadata(target, os.path.abspath(ei.egg_info)), project_name=ei.egg_name) p = self.egg_base.replace(os.sep, '/') if p != os.curdir: p = '../' * (p.count('/') + 1) self.setup_path = p p = normalize_path(os.path.join(self.install_dir, self.egg_path, p)) if p != normalize_path(os.curdir): raise DistutilsOptionError( "Can't get a consistent path to setup script from" " installation directory", p, normalize_path(os.curdir))
def interpret_distro_name(location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None): """Generate alternative interpretations of a source distro name Note: if `location` is a filesystem filename, you should call ``pkg_resources.normalize_path()`` on it before passing it to this routine! """ # Generate alternative interpretations of a source distro name # Because some packages are ambiguous as to name/versions split # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc. # So, we generate each possible interepretation (e.g. "adns, python-1.1.0" # "adns-python, 1.1.0", and "adns-python-1.1.0, no version"). In practice, # the spurious interpretations should be ignored, because in the event # there's also an "adns" package, the spurious "python-1.1.0" version will # compare lower than any numeric version number, and is therefore unlikely # to match a request for it. It's still a potential problem, though, and # in the long run PyPI and the distutils should go for "safe" names and # versions in distribution archive names (sdist and bdist). parts = basename.split('-') if not py_version and any(re.match('py\d\.\d$', p) for p in parts[2:]): # it is a bdist_dumb, not an sdist -- bail out return for p in range(1, len(parts) + 1): yield Distribution(location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]), py_version=py_version, precedence=precedence, platform=platform)
def egg_name(self): return Distribution( project_name=self.project_name, version=self.version, platform=(None if self.platform == 'any' else get_platform()), ).egg_name() + '.egg'
def get_distrib(*dep_ver_pairs): """Build some Distributions with indicated info.""" return [ Distribution(project_name=dep, version=ver) for dep, ver in dep_ver_pairs ]
def install_as_egg(self, destination_eggdir): '''Install wheel as an egg directory.''' with zipfile.ZipFile(self.filename) as zf: dist_basename = '%s-%s' % (self.project_name, self.version) dist_info = '%s.dist-info' % dist_basename dist_data = '%s.data' % dist_basename def get_metadata(name): with zf.open('%s/%s' % (dist_info, name)) as fp: value = fp.read().decode('utf-8') if PY3 else fp.read() return email.parser.Parser().parsestr(value) wheel_metadata = get_metadata('WHEEL') dist_metadata = get_metadata('METADATA') # Check wheel format version is supported. wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) if not parse_version('1.0') <= wheel_version < parse_version( '2.0dev0'): raise ValueError('unsupported wheel format version: %s' % wheel_version) # Extract to target directory. os.mkdir(destination_eggdir) zf.extractall(destination_eggdir) # Convert metadata. dist_info = os.path.join(destination_eggdir, dist_info) dist = Distribution.from_location(destination_eggdir, dist_info, metadata=PathMetadata( destination_eggdir, dist_info)) # Note: we need to evaluate and strip markers now, # as we can't easily convert back from the syntax: # foobar; "linux" in sys_platform and extra == 'test' def raw_req(req): req.marker = None return str(req) install_requires = list(sorted(map(raw_req, dist.requires()))) extras_require = { extra: list( sorted(req for req in map(raw_req, dist.requires((extra, ))) if req not in install_requires)) for extra in dist.extras } egg_info = os.path.join(destination_eggdir, 'EGG-INFO') os.rename(dist_info, egg_info) os.rename(os.path.join(egg_info, 'METADATA'), os.path.join(egg_info, 'PKG-INFO')) setup_dist = SetuptoolsDistribution(attrs=dict( install_requires=install_requires, extras_require=extras_require, )) write_requirements(setup_dist.get_command_obj('egg_info'), None, os.path.join(egg_info, 'requires.txt')) # Move data entries to their correct location. dist_data = os.path.join(destination_eggdir, dist_data) dist_data_scripts = os.path.join(dist_data, 'scripts') if os.path.exists(dist_data_scripts): egg_info_scripts = os.path.join(destination_eggdir, 'EGG-INFO', 'scripts') os.mkdir(egg_info_scripts) for entry in os.listdir(dist_data_scripts): # Remove bytecode, as it's not properly handled # during easy_install scripts install phase. if entry.endswith('.pyc'): os.unlink(os.path.join(dist_data_scripts, entry)) else: os.rename(os.path.join(dist_data_scripts, entry), os.path.join(egg_info_scripts, entry)) os.rmdir(dist_data_scripts) for subdir in filter( os.path.exists, (os.path.join(dist_data, d) for d in ('data', 'headers', 'purelib', 'platlib'))): unpack(subdir, destination_eggdir) if os.path.exists(dist_data): os.rmdir(dist_data) # Fix namespace packages. namespace_packages = os.path.join(egg_info, 'namespace_packages.txt') if os.path.exists(namespace_packages): with open(namespace_packages) as fp: namespace_packages = fp.read().split() for mod in namespace_packages: mod_dir = os.path.join(destination_eggdir, *mod.split('.')) mod_init = os.path.join(mod_dir, '__init__.py') if os.path.exists( mod_dir) and not os.path.exists(mod_init): with open(mod_init, 'w') as fp: fp.write(NAMESPACE_PACKAGE_INIT)
def get_mock_plugin(name, version, reg=None, alias=None, after=None, rules=None, target_types=None): """Make a fake Distribution (optionally with entry points) Note the entry points do not actually point to code in the returned distribution -- the distribution does not even have a location and does not contain any code, just metadata. A module is synthesized on the fly and installed into sys.modules under a random name. If optional entry point callables are provided, those are added as methods to the module and their name (foo/bar/baz in fake module) is added as the requested entry point to the mocked metadata added to the returned dist. :param string name: project_name for distribution (see pkg_resources) :param string version: version for distribution (see pkg_resources) :param callable reg: Optional callable for goal registration entry point :param callable alias: Optional callable for build_file_aliases entry point :param callable after: Optional callable for load_after list entry point :param callable rules: Optional callable for rules entry point :param callable target_types: Optional callable for target_types entry point """ plugin_pkg = f"demoplugin{uuid.uuid4().hex}" pkg = types.ModuleType(plugin_pkg) sys.modules[plugin_pkg] = pkg module_name = f"{plugin_pkg}.demo" plugin = types.ModuleType(module_name) setattr(pkg, "demo", plugin) sys.modules[module_name] = plugin metadata = {} entry_lines = [] if reg is not None: setattr(plugin, "foo", reg) entry_lines.append(f"register_goals = {module_name}:foo\n") if alias is not None: setattr(plugin, "bar", alias) entry_lines.append(f"build_file_aliases = {module_name}:bar\n") if after is not None: setattr(plugin, "baz", after) entry_lines.append(f"load_after = {module_name}:baz\n") if rules is not None: setattr(plugin, "qux", rules) entry_lines.append(f"rules = {module_name}:qux\n") if target_types is not None: setattr(plugin, "tofu", target_types) entry_lines.append(f"target_types = {module_name}:tofu\n") if entry_lines: entry_data = "[pantsbuild.plugin]\n{}\n".format( "\n".join(entry_lines)) metadata = {"entry_points.txt": entry_data} return Distribution(project_name=name, version=version, metadata=MockMetadata(metadata))
def create_fake_distribution(name): return Distribution(project_name="cerberus", version="1.2.3")
def setUp(self): self.dist = Distribution.from_filename( "FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt','[x]')))
#!/usr/bin/python # Copyright (C) 2008, Charles Wang <*****@*****.**> # Author: Charles Wang <*****@*****.**> # License: BSD import os.path import shutil import sys from pkg_resources import Distribution from pypi2pkgsys.package_system import package_system from pypi2pkgsys.pypi_objects import pypicache if len(sys.argv) < 4: print 'Usage: %s CACHE_ROOT CACHE_URL FILENAME,DISTNAME ...' % sys.argv[0] sys.exit(-1) cacheroot = sys.argv[1] cacheurl = sys.argv[2] downloads = os.path.join(cacheroot, 'downloads') distlist = [] for arg in sys.argv[3:]: filename, distname = arg.split(',') dlfname = os.path.join(downloads, os.path.basename(filename)) print 'Copy %s %s ...' % (filename, dlfname) shutil.copyfile(filename, dlfname) dist = Distribution(dlfname, None, project_name=distname) distlist.append(dist) cache = pypicache(package_system(), cacheroot, cacheurl) cache.add_packages(distlist) del (cache)
import pluginlib._loader as loader from pluginlib import BlacklistEntry, PluginImportError, EntryPointWarning from tests import TestCase, OUTPUT, mock import tests.testdata import tests.testdata.parents try: from importlib import reload except ImportError: pass DATAPATH = os.path.dirname(tests.testdata.__file__) DIST = Distribution.from_filename(tests.testdata.__file__) working_set.add(DIST) DIST._ep_map = {} # pylint: disable=protected-access class TestPluginLoaderInit(TestCase): """Tests for initialization of PluginLoader""" def test_bad_arguments(self): """Error is raised when argument type is wrong""" # Expect iterables for arg in ('modules', 'paths', 'blacklist', 'type_filter'): with self.assertRaises(TypeError): loader.PluginLoader(**{arg: 'string'})
def get_mock_plugin(self, name, version, reg=None, alias=None, after=None, rules=None): """Make a fake Distribution (optionally with entry points) Note the entry points do not actually point to code in the returned distribution -- the distribution does not even have a location and does not contain any code, just metadata. A module is synthesized on the fly and installed into sys.modules under a random name. If optional entry point callables are provided, those are added as methods to the module and their name (foo/bar/baz in fake module) is added as the requested entry point to the mocked metadata added to the returned dist. :param string name: project_name for distribution (see pkg_resources) :param string version: version for distribution (see pkg_resources) :param callable reg: Optional callable for goal registration entry point :param callable alias: Optional callable for build_file_aliases entry point :param callable after: Optional callable for load_after list entry point :param callable rules: Optional callable for rules entry point """ plugin_pkg = 'demoplugin{0}'.format(uuid.uuid4().hex) if PY2: plugin_pkg = plugin_pkg.encode('utf-8') pkg = types.ModuleType(plugin_pkg) sys.modules[plugin_pkg] = pkg module_name = '{0}.{1}'.format(plugin_pkg, 'demo') if PY2: module_name = module_name.encode('utf-8') plugin = types.ModuleType(module_name) setattr(pkg, 'demo', plugin) sys.modules[module_name] = plugin metadata = {} entry_lines = [] if reg is not None: setattr(plugin, 'foo', reg) entry_lines.append('register_goals = {}:foo\n'.format(module_name)) if alias is not None: setattr(plugin, 'bar', alias) entry_lines.append( 'build_file_aliases = {}:bar\n'.format(module_name)) if after is not None: setattr(plugin, 'baz', after) entry_lines.append('load_after = {}:baz\n'.format(module_name)) if rules is not None: setattr(plugin, 'qux', rules) entry_lines.append('rules = {}:qux\n'.format(module_name)) if entry_lines: entry_data = '[pantsbuild.plugin]\n{}\n'.format( '\n'.join(entry_lines)) metadata = {'entry_points.txt': entry_data} return Distribution(project_name=name, version=version, metadata=MockMetadata(metadata))
def finalize_options(self): ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: raise DistutilsError( "Please rename %r to %r before using 'develop'" % (ei.egg_info, ei.broken_egg_info) ) self.args = [ei.egg_name] py_version = sys.version.split()[0] prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix') self.config_vars = {'dist_name': self.distribution.get_name(), 'dist_version': self.distribution.get_version(), 'dist_fullname': self.distribution.get_fullname(), 'py_version': py_version, 'py_version_short': py_version[0:3], 'py_version_nodot': py_version[0] + py_version[2], 'sys_prefix': prefix, 'prefix': prefix, 'sys_exec_prefix': exec_prefix, 'exec_prefix': exec_prefix, } if HAS_USER_SITE: self.config_vars['userbase'] = self.install_userbase self.config_vars['usersite'] = self.install_usersite # fix the install_dir if "--user" was used if self.user: self.create_home_path() if self.install_userbase is None: raise DistutilsPlatformError( "User base directory is not specified") self.install_base = self.install_platbase = self.install_userbase if os.name == 'posix': self.select_scheme("unix_user") else: self.select_scheme(os.name + "_user") self.expand_basedirs() self.expand_dirs() if self.user and self.install_purelib: self.install_dir = self.install_purelib self.script_dir = self.install_scripts easy_install.finalize_options(self) # pick up setup-dir .egg files only: no .egg-info self.package_index.scan(glob.glob('*.egg')) self.egg_link = os.path.join(self.install_dir, ei.egg_name+'.egg-link') self.egg_base = ei.egg_base if self.egg_path is None: self.egg_path = os.path.abspath(ei.egg_base) target = normalize_path(self.egg_base) if normalize_path(os.path.join(self.install_dir, self.egg_path)) != target: raise DistutilsOptionError( "--egg-path must be a relative path from the install" " directory to "+target ) # Make a distribution for the package's source self.dist = Distribution( target, PathMetadata(target, os.path.abspath(ei.egg_info)), project_name = ei.egg_name ) p = self.egg_base.replace(os.sep,'/') if p!= os.curdir: p = '../' * (p.count('/')+1) self.setup_path = p p = normalize_path(os.path.join(self.install_dir, self.egg_path, p)) if p != normalize_path(os.curdir): raise DistutilsOptionError( "Can't get a consistent path to setup script from" " installation directory", p, normalize_path(os.curdir))
def get_pkg_info_version(pkg_info_file): dist_info = Distribution.from_filename(CURRENT_DIR / "pyjadx.egg-info") pkg = get_distribution('pyjadx') return pkg.version
def get_pkg_info_version(pkg_info_file): dist_info = Distribution.from_filename( os.path.join(CURRENT_DIR, "{}.egg-info".format(PACKAGE_NAME))) pkg = get_distribution('lief') return pkg.version
def _mock_distribution(name): return Distribution(version='1.2.3')
def distRequires(self, txt): return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
def distribution(self): base_dir = self.root() egg_info = self.egg_info() metadata = PathMetadata(base_dir, egg_info) return Distribution.from_location(base_dir, os.path.basename(egg_info), metadata=metadata)
def distribution(self): return Distribution(project_name=self.interpreter, version=self.version_str)
# -*- coding: utf-8 -*- import io from pkg_resources import Distribution from pkg_resources import EntryPoint from pkg_resources import EmptyProvider from setuptools.command.egg_info import egg_info _dist = Distribution() dummy = object() class WorkingSet(object): def __init__(self, items, dist=_dist): self.items = items self.dist = dist def iter_entry_points(self, name): items = self.items.get(name, []) for item in items: entry_point = item if isinstance( item, EntryPoint) else EntryPoint.parse(item) entry_point.dist = self.dist yield entry_point def find(self, name): # just always return the dist. return self.dist
lower = lower_dir f = dirname(f) # Determine provide, requires, conflicts & recommends based on egg/dist metadata if lower.endswith('.egg') or \ lower.endswith('.egg-info') or \ lower.endswith('.dist-info'): # This import is very slow, so only do it if needed from pkg_resources import Distribution, FileMetadata, PathMetadata, Requirement dist_name = basename(f) if isdir(f): path_item = dirname(f) metadata = PathMetadata(path_item, f) else: path_item = f metadata = FileMetadata(f) dist = Distribution.from_location(path_item, dist_name, metadata) # Check if py_version is defined in the metadata file/directory name if not dist.py_version: # Try to parse the Python version from the path the metadata # resides at (e.g. /usr/lib/pythonX.Y/site-packages/...) import re res = re.search(r"/python(?P<pyver>\d+\.\d)/", path_item) if res: dist.py_version = res.group('pyver') else: warn("Version for {!r} has not been found".format(dist), RuntimeWarning) continue if Provides_PyMajorVer_Variant or PyMajorVer_Deps or legacy_Provides or legacy: # Get the Python major version pyver_major = dist.py_version.split('.')[0]
def distribution(self): return Distribution(project_name=self._interpreter, version='.'.join(map(str, self._version)))
assert_equal( parse_editable('.[extras]', 'git'), (None, 'file://' + "/some/path", ('extras',)) ) normcase_mock.return_value = "/some/path/foo" assert_equal( parse_editable('foo[bar,baz]', 'git'), (None, 'file:///some/path/foo', ('bar', 'baz')) ) def test_remote_reqs_parse(): """ Test parsing a simple remote requirements file """ # this requirements file just contains a comment # previously this has failed in py3 (https://github.com/pypa/pip/issues/760) for req in parse_requirements('https://raw.github.com/pypa/pip-test-package/master/tests/req_just_comment.txt'): pass # patch this for travis which has distribute in it's base env for now @patch('pip.wheel.pkg_resources.get_distribution', lambda x: Distribution(project_name='setuptools', version='0.9')) def test_req_file_parse_use_wheel(): """ Test parsing --use-wheel from a req file """ reqfile = os.path.join(tests_data, 'reqfiles', 'supported_options.txt') finder = PackageFinder([], []) for req in parse_requirements(reqfile, finder): pass assert finder.use_wheel
import unittest from os import path from pkg_resources import Distribution, EntryPoint from nichtparasoup.imagecrawler import KnownImageCrawlers from .testdata_imagecrawler_plugin import ( BaseLoadableImageCrawlerA, LoadableImageCrawlerA, LoadableImageCrawlerB, StandaloneLoadableImageCrawlerA, ) _TEST_PLUGIN_DIST = Distribution( location=path.abspath('testdata_imagecrawler_plugin'), project_name='testdata-imagecrawler-plugin') _TEST_PLUGIN_CLASS = LoadableImageCrawlerA _TEST_PLUGIN_ENTRY = EntryPoint('Test', _TEST_PLUGIN_CLASS.__module__, attrs=(_TEST_PLUGIN_CLASS.__name__, ), dist=_TEST_PLUGIN_DIST) class KnownImageCrawlersLoadTest(unittest.TestCase): def test_success(self) -> None: # arrange entry = _TEST_PLUGIN_ENTRY # act loaded = KnownImageCrawlers._load(entry) # assert