def _pip_combine_key(spec): parsed = pip_api.parse_spec(spec) if parsed is None: # this is broken but we complain about it in project.py, carry on here return spec else: return parsed.name
def __init__(self, name, conda_packages, channels, pip_packages=(), description=None, inherit_from_names=(), inherit_from=()): """Construct a package set with the given name and packages. Args: name (str): name of the package set conda_packages (list): list of package specs to pass to conda install channels (list): list of channel names pip_packages (list): list of pip package specs to pass to pip description (str or None): one-sentence-ish summary of what this env is inherit_from_name (str or None): name of what we inherit from inherit_from (EnvSpec or None): pull in packages and channels from """ assert inherit_from_names is not None assert inherit_from is not None self._name = name self._conda_packages = tuple(conda_packages) self._channels = tuple(channels) self._pip_packages = tuple(pip_packages) self._description = description self._channels_and_packages_hash = None self._inherit_from_names = inherit_from_names self._inherit_from = inherit_from # inherit_from must be a subset of inherit_from_names # except that we can have an anonymous base env spec for # the global packages/channels sections; if there was an # error that kept us from creating one of the specs we # name as a parent, then self._inherit_from would be a # subset rather than equal. for name in tuple([spec.name for spec in self._inherit_from]): assert name is None or name in self._inherit_from_names conda_specs_by_name = dict() for spec in self.conda_packages: # we quietly skip invalid specs here and let them fail # somewhere we can more easily report an error message. parsed = conda_api.parse_spec(spec) if parsed is not None: conda_specs_by_name[parsed.name] = spec self._conda_specs_by_name = conda_specs_by_name pip_specs_by_name = dict() for spec in self.pip_packages: # we quietly skip invalid specs here and let them fail # somewhere we can more easily report an error message. parsed = pip_api.parse_spec(spec) if parsed is not None: pip_specs_by_name[parsed.name] = spec self._pip_specs_by_name = pip_specs_by_name
def test_parse_spec_url(): assert "bar" == pip_api.parse_spec("http://example.com/foo#egg=bar").name assert "bar" == pip_api.parse_spec("https://example.com/foo#egg=bar").name # ignore after extra & assert "bar" == pip_api.parse_spec("https://example.com/foo#egg=bar&subdirectory=blah").name # ignore "-1.3" type of stuff after the package name assert "bar" == pip_api.parse_spec("https://example.com/foo#egg=bar-1.3").name # ignore if no #egg fragment assert pip_api.parse_spec("http://example.com/foo") is None # this was a real-world example with an url and [] after package name assert 'dask' == pip_api.parse_spec('git+https://github.com/blaze/dask.git#egg=dask[complete]').name
def test_parse_spec(): # just a package name assert "foo" == pip_api.parse_spec("foo").name # ignore leading whitespace assert "foo" == pip_api.parse_spec(" foo").name # non-alphanumeric names not ok assert pip_api.parse_spec("=") is None assert pip_api.parse_spec("%%") is None # ignore the version specifier stuff assert "foo" == pip_api.parse_spec("foo==1.3").name # these three punctuation chars are allowed assert "a-_." == pip_api.parse_spec("a-_.").name # we use this in some tests assert "nope_not_a_thing" == pip_api.parse_spec("nope_not_a_thing").name # a bunch of examples from the pip docs for spec in ['SomeProject', 'SomeProject == 1.3', 'SomeProject >=1.2,<.2.0', 'SomeProject[foo, bar]', 'SomeProject~=1.4.2', "SomeProject ==5.4 ; python_version < '2.7'", "SomeProject; sys_platform == 'win32'"]: assert "SomeProject" == pip_api.parse_spec(spec).name
def __init__(self, name, conda_packages, channels, pip_packages=(), description=None, inherit_from_names=(), inherit_from=(), platforms=(), lock_set=None): """Construct a package set with the given name and packages. Args: name (str): name of the package set conda_packages (list): list of package specs to pass to conda install channels (list): list of channel names pip_packages (list): list of pip package specs to pass to pip description (str or None): one-sentence-ish summary of what this env is inherit_from_name (str or None): name of what we inherit from inherit_from (EnvSpec or None): pull in packages and channels from lock_set (CondaLockSet): locked packages or None """ assert inherit_from_names is not None assert inherit_from is not None self._name = name self._path = None self._readonly = None self._conda_packages = tuple(conda_packages) self._channels = tuple(channels) self._pip_packages = tuple(pip_packages) self._description = description self._logical_hash = None self._locked_hash = None self._import_hash = None self._inherit_from_names = inherit_from_names self._inherit_from = inherit_from self._lock_set = lock_set self._platforms = tuple(conda_api.sort_platform_list(platforms)) # inherit_from must be a subset of inherit_from_names # except that we can have an anonymous base env spec for # the global packages/channels sections; if there was an # error that kept us from creating one of the specs we # name as a parent, then self._inherit_from would be a # subset rather than equal. for name in tuple([spec.name for spec in self._inherit_from]): assert name is None or name in self._inherit_from_names conda_specs_by_name = dict() for spec in self.conda_packages_for_create: # we quietly skip invalid specs here and let them fail # somewhere we can more easily report an error message. parsed = conda_api.parse_spec(spec) if parsed is not None: conda_specs_by_name[parsed.name] = spec self._conda_specs_for_create_by_name = conda_specs_by_name name_set = set() conda_constrained_packages = [] for spec in self.conda_packages: parsed = conda_api.parse_spec(spec) if parsed is not None: name_set.add(parsed.name) if parsed.conda_constraint is not None or parsed.pip_constraint is not None: conda_constrained_packages.append(spec) self._conda_logical_specs_name_set = name_set self.conda_constrained_packages = sorted(conda_constrained_packages) pip_specs_by_name = dict() for spec in self.pip_packages_for_create: # we quietly skip invalid specs here and let them fail # somewhere we can more easily report an error message. parsed = pip_api.parse_spec(spec) if parsed is not None: pip_specs_by_name[parsed.name] = spec self._pip_specs_for_create_by_name = pip_specs_by_name name_set = set() for spec in self.pip_packages: parsed = pip_api.parse_spec(spec) if parsed is not None: name_set.add(parsed.name) self._pip_logical_specs_name_set = name_set self._conda = conda_manager.new_conda_manager()