PackageRecord#
PackageRecord
#
A single record in the Conda repodata. A single record refers to a single binary distribution of a package on a Conda channel.
constrains: List[str]
property
writable
#
Additional constraints on packages. Constrains are different from depends in that packages specified in depends must be installed next to this package, whereas packages specified in constrains are not required to be installed, but if they are installed they must follow these constraints.
Examples#
depends: List[str]
property
writable
#
Specification of packages this package depends on.
Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.depends
['ucrt >=10.0.20348.0', 'vc >=14.2,<15', 'vs2015_runtime >=14.29.30139']
>>> record.depends = ["python >=3.6"]
>>> record.depends
['python >=3.6']
>>>
features: Optional[str]
property
writable
#
Features are a deprecated way to specify different feature sets for the conda solver. This is not supported anymore and should not be used. Instead, mutex packages should be used to specify mutually exclusive features.
Examples#
legacy_bz2_md5: Optional[bytes]
property
writable
#
A deprecated md5 hash.
Examples#
>>> record = PackageRecord.from_index_json(
... "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> record.legacy_bz2_md5 is None
True
>>> record.legacy_bz2_md5 = bytes.fromhex("2ddbbaf3a82b46ac7214681262e3d746")
>>> record.legacy_bz2_md5.hex()
'2ddbbaf3a82b46ac7214681262e3d746'
>>> record.legacy_bz2_md5 = None
>>> record.legacy_bz2_md5 is None
True
>>>
license_family: Optional[str]
property
writable
#
The license family.
Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/pip-23.0-pyhd8ed1ab_0.json"
... )
>>> record.license_family
'MIT'
>>> record.license_family = "BSD"
>>> record.license_family
'BSD'
>>> record.license_family = None
>>> record.license_family is None
True
>>>
md5: Optional[bytes]
property
writable
#
Optionally a MD5 hash of the package archive.
Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.md5.hex()
'5e5a97795de72f8cc3baf3d9ea6327a2'
>>> record.md5 = bytes.fromhex("2ddbbaf3a82b46ac7214681262e3d746")
>>> record.md5.hex()
'2ddbbaf3a82b46ac7214681262e3d746'
>>> record.md5 = None
>>> record.md5 is None
True
>>>
noarch: NoArchType
property
writable
#
The noarch type of the package.
Examples#
>>> from rattler import PrefixRecord
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.noarch
NoArchType(None)
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/pip-23.0-pyhd8ed1ab_0.json"
... )
>>> record.noarch
NoArchType("python")
>>> record.noarch = NoArchType("generic")
>>> record.noarch
NoArchType("generic")
>>> record.noarch = NoArchType(None)
>>> record.noarch.none
True
>>>
python_site_packages_path: Optional[str]
property
writable
#
Optionally a path within the environment of the site-packages directory. This field is only present for python interpreter packages. This field was introduced with https://github.com/conda/ceps/blob/main/cep-17.md.
Examples#
sha256: Optional[bytes]
property
writable
#
Optionally a SHA256 hash of the package archive.
Examples#
```python
from rattler import PrefixRecord record = PrefixRecord.from_path( ... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json" ... ) record.sha256.hex() '4e50b3d90a351c9d47d239d3f90fce4870df2526e4f7fef35203ab3276a6dfc9' record.sha256 = bytes.fromhex("edd7dd24fc070fad8ca690a920d94b6312a376faa96b47c657f9ef5fe5a97dd1") record.sha256.hex() 'edd7dd24fc070fad8ca690a920d94b6312a376faa96b47c657f9ef5fe5a97dd1' record.sha256 = None record.sha256 is None True
size: Optional[int]
property
writable
#
Optionally the size of the package archive in bytes.
Examples#
timestamp: Optional[datetime.datetime]
property
writable
#
The date this entry was created.
Examples#
>>> from rattler import PrefixRecord
>>> import datetime
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.timestamp
datetime.datetime(2022, 11, 17, 15, 7, 19, 781000, tzinfo=datetime.timezone.utc)
>>> new_time = datetime.datetime(2023, 1, 1, tzinfo=datetime.timezone.utc)
>>> record.timestamp = new_time
>>> record.timestamp
datetime.datetime(2023, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
>>> record.timestamp = None
>>> record.timestamp is None
True
>>>
track_features: List[str]
property
writable
#
Track features are nowadays only used to downweight packages (ie. give them less priority). To that effect, the number of track features is counted (number of commas) and the package is downweighted by the number of track_features.
Examples#
version: VersionWithSource
property
writable
#
The version of the package.
Examples#
>>> from rattler import PrefixRecord, VersionWithSource
>>> record = PrefixRecord.from_path(
... "../test-data/conda-meta/libsqlite-3.40.0-hcfcfb64_0.json"
... )
>>> record.version
VersionWithSource(version="3.40.0", source="3.40.0")
>>> record.version = VersionWithSource("1.0.0")
>>> record.version
VersionWithSource(version="1.0.0", source="1.0.0")
>>>
from_index_json(path, size=None, sha256=None, md5=None)
staticmethod
#
Builds a PackageRecord from an index.json
.
These can be found in info
directory inside an
extracted package archive.
Examples#
>>> record = PackageRecord.from_index_json(
... "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> assert isinstance(record, PackageRecord)
>>> record.name
PackageName("pysocks")
>>> record.version
VersionWithSource(version="1.7.1", source="1.7.1")
>>> record.build
'pyh0701188_6'
>>>
matches(spec)
#
Match a [PackageRecord
] against a [MatchSpec
].
Examples#
>>> from rattler import MatchSpec
>>> record = PackageRecord.from_index_json(
... "../test-data/conda-meta/pysocks-1.7.1-pyh0701188_6.json"
... )
>>> spec = MatchSpec("pysocks")
>>> record.matches(spec)
True
>>> spec = MatchSpec("pysocks>=1.7")
>>> record.matches(spec)
True
>>> spec = MatchSpec("pysocks<1.7")
>>> record.matches(spec)
False
>>>
sort_topologically(records)
staticmethod
#
Sorts the records topologically. This function is deterministic, meaning that it will return the same result regardless of the order of records and of the depends vector inside the records. Note that this function only works for packages with unique names.
Examples#
>>> from os import listdir
>>> from os.path import isfile, join
>>> from rattler import PrefixRecord
>>> records = [
... PrefixRecord.from_path(join("../test-data/conda-meta/", f))
... for f in listdir("../test-data/conda-meta")
... if isfile(join("../test-data/conda-meta", f))
... ]
>>> sorted = PackageRecord.sort_topologically(records)
>>> sorted[0].name
PackageName("python_abi")
>>> # Verify it's deterministic by sorting again
>>> sorted2 = PackageRecord.sort_topologically(records)
>>> [str(r) for r in sorted] == [str(r) for r in sorted2]
True
>>>
to_graph(records)
staticmethod
#
Converts a list of PackageRecords to a DAG (networkx.DiGraph
).
The nodes in the graph are the PackageRecords and the edges are the dependencies.
Note: Virtual packages (starting with __
) are skipped.
validate(records)
staticmethod
#
Validate that the given package records are valid w.r.t. 'depends' and 'constrains'.
This function will return nothing if all records form a valid environment, i.e., all dependencies of each package are satisfied by the other packages in the list. If there is a dependency that is not satisfied, this function will raise an exception.
Examples#
>>> from os import listdir
>>> from os.path import isfile, join
>>> from rattler import PrefixRecord
>>> from rattler.exceptions import ValidatePackageRecordsException
>>> records = [
... PrefixRecord.from_path(join("../test-data/conda-meta/", f))
... for f in sorted(listdir("../test-data/conda-meta"))
... if isfile(join("../test-data/conda-meta", f))
... ]
>>> try:
... PackageRecord.validate(records)
... except ValidatePackageRecordsException as e:
... print(e)
package 'libsqlite=3.40.0=hcfcfb64_0' has dependency 'ucrt >=10.0.20348.0', which is not in the environment
>>>