Skip to content

Commit 3c457aa

Browse files
authored
feat: add IndexJson (#567)
1 parent 5f3350a commit 3c457aa

File tree

8 files changed

+514
-3
lines changed

8 files changed

+514
-3
lines changed

py-rattler/Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

py-rattler/docs/index_json.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# IndexJson
2+
3+
::: rattler.package.index_json

py-rattler/mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ nav:
4949
- metadata:
5050
- AboutJson: about_json.md
5151
- RunExportsJson: run_exports_json.md
52+
- IndexJson: index_json.md
5253
- match_spec:
5354
- MatchSpec: match_spec.md
5455
- NamelessMatchSpec: nameless_match_spec.md

py-rattler/rattler/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from rattler.channel import Channel, ChannelConfig
1111
from rattler.networking import AuthenticatedClient, fetch_repo_data
1212
from rattler.virtual_package import GenericVirtualPackage, VirtualPackage
13-
from rattler.package import PackageName, AboutJson, RunExportsJson
13+
from rattler.package import PackageName, AboutJson, RunExportsJson, IndexJson
1414
from rattler.prefix import PrefixRecord, PrefixPaths
1515
from rattler.solver import solve
1616
from rattler.platform import Platform
@@ -62,4 +62,5 @@
6262
"index",
6363
"AboutJson",
6464
"RunExportsJson",
65+
"IndexJson",
6566
]
+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from rattler.package.package_name import PackageName
22
from rattler.package.about_json import AboutJson
33
from rattler.package.run_exports_json import RunExportsJson
4+
from rattler.package.index_json import IndexJson
45

5-
__all__ = ["PackageName", "AboutJson", "RunExportsJson"]
6+
__all__ = ["PackageName", "AboutJson", "RunExportsJson", "IndexJson"]
+341
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
from __future__ import annotations
2+
import os
3+
from pathlib import Path
4+
from typing import List, Optional
5+
6+
from rattler.package.package_name import PackageName
7+
from rattler.rattler import PyIndexJson
8+
9+
10+
class IndexJson:
11+
_inner: PyIndexJson
12+
13+
@staticmethod
14+
def from_package_archive(path: os.PathLike[str]) -> IndexJson:
15+
"""
16+
Parses the package file from archive.
17+
Note: If you want to extract multiple `info/*` files then this will be slightly
18+
slower than manually iterating over the archive entries with
19+
custom logic as this skips over the rest of the archive
20+
21+
Examples
22+
--------
23+
```python
24+
>>> idx_json = IndexJson.from_package_archive(
25+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
26+
... )
27+
>>> idx_json
28+
IndexJson()
29+
>>>
30+
```
31+
"""
32+
return IndexJson._from_py_index_json(PyIndexJson.from_package_archive(path))
33+
34+
@staticmethod
35+
def from_package_directory(path: os.PathLike[str]) -> IndexJson:
36+
"""
37+
Parses the object by looking up the appropriate file from the root of the
38+
specified Conda archive directory, using a format appropriate for the file
39+
type.
40+
41+
For example, if the file is in JSON format, this function reads the
42+
appropriate file from the archive, parse the JSON string and return the
43+
resulting object. If the file is not in a parsable format or if the file
44+
could not be read, this function returns an error.
45+
"""
46+
return IndexJson._from_py_index_json(
47+
PyIndexJson.from_package_directory(Path(path))
48+
)
49+
50+
@staticmethod
51+
def from_str(string: str) -> IndexJson:
52+
"""
53+
Parses the object from a string, using a format appropriate for the file
54+
type.
55+
56+
For example, if the file is in JSON format, this function parses the JSON
57+
string and returns the resulting object. If the file is not in a parsable
58+
format, this function returns an error.
59+
"""
60+
return IndexJson._from_py_index_json(PyIndexJson.from_str(string))
61+
62+
@staticmethod
63+
def package_path() -> str:
64+
"""
65+
Returns the path to the file within the Conda archive.
66+
67+
The path is relative to the root of the archive and includes any necessary
68+
directories.
69+
"""
70+
return PyIndexJson.package_path()
71+
72+
@property
73+
def arch(self) -> Optional[str]:
74+
"""
75+
Optionally, the architecture the package is build for.
76+
77+
Examples
78+
--------
79+
```python
80+
>>> idx_json = IndexJson.from_package_archive(
81+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
82+
... )
83+
>>> idx_json.arch
84+
'ppc64le'
85+
>>>
86+
```
87+
"""
88+
if arch := self._inner.arch:
89+
return arch
90+
91+
return None
92+
93+
@property
94+
def build(self) -> str:
95+
"""
96+
The build string of the package.
97+
98+
Examples
99+
--------
100+
```python
101+
>>> idx_json = IndexJson.from_package_archive(
102+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
103+
... )
104+
>>> idx_json.build
105+
'h2c4edbf_0_cpython'
106+
>>>
107+
```
108+
"""
109+
return self._inner.build
110+
111+
@property
112+
def build_number(self) -> int:
113+
"""
114+
The build number of the package.
115+
This is also included in the build string.
116+
117+
Examples
118+
--------
119+
```python
120+
>>> idx_json = IndexJson.from_package_archive(
121+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
122+
... )
123+
>>> idx_json.build_number
124+
0
125+
>>>
126+
```
127+
"""
128+
return self._inner.build_number
129+
130+
@property
131+
def constrains(self) -> List[str]:
132+
"""
133+
The package constraints of the package.
134+
135+
Examples
136+
--------
137+
```python
138+
>>> idx_json = IndexJson.from_package_archive(
139+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
140+
... )
141+
>>> idx_json.constrains
142+
['python_abi 3.10.* *_cp310']
143+
>>>
144+
```
145+
"""
146+
return self._inner.constrains
147+
148+
@property
149+
def depends(self) -> List[str]:
150+
"""
151+
The dependencies of the package.
152+
153+
Examples
154+
--------
155+
```python
156+
>>> idx_json = IndexJson.from_package_archive(
157+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
158+
... )
159+
>>> idx_json.depends
160+
['bzip2 >=1.0.8,<2.0a0', ..., 'xz >=5.2.6,<5.3.0a0']
161+
>>>
162+
```
163+
"""
164+
return self._inner.depends
165+
166+
@property
167+
def features(self) -> Optional[str]:
168+
"""
169+
Features are a deprecated way to specify different feature sets for the conda solver. This is not
170+
supported anymore and should not be used. Instead, `mutex` packages should be used to specify
171+
mutually exclusive features.
172+
173+
Examples
174+
--------
175+
```python
176+
>>> idx_json = IndexJson.from_package_archive(
177+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
178+
... )
179+
>>> idx_json.features
180+
>>>
181+
```
182+
"""
183+
if features := self._inner.features:
184+
return features
185+
186+
return None
187+
188+
@property
189+
def license(self) -> Optional[str]:
190+
"""
191+
Optionally, the license.
192+
193+
Examples
194+
--------
195+
```python
196+
>>> idx_json = IndexJson.from_package_archive(
197+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
198+
... )
199+
>>> idx_json.license
200+
'Python-2.0'
201+
>>>
202+
```
203+
"""
204+
if license := self._inner.license:
205+
return license
206+
207+
return None
208+
209+
@property
210+
def license_family(self) -> Optional[str]:
211+
"""
212+
Optionally, the license.
213+
214+
Examples
215+
--------
216+
```python
217+
>>> idx_json = IndexJson.from_package_archive(
218+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
219+
... )
220+
>>> idx_json.license_family
221+
>>>
222+
```
223+
"""
224+
if license_family := self._inner.license_family:
225+
return license_family
226+
227+
return None
228+
229+
@property
230+
def name(self) -> PackageName:
231+
"""
232+
The lowercase name of the package.
233+
234+
Examples
235+
--------
236+
```python
237+
>>> idx_json = IndexJson.from_package_archive(
238+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
239+
... )
240+
>>> idx_json.name
241+
PackageName("python")
242+
>>>
243+
```
244+
"""
245+
return PackageName._from_py_package_name(self._inner.name)
246+
247+
@property
248+
def platform(self) -> Optional[str]:
249+
"""
250+
Optionally, the OS the package is build for.
251+
252+
Examples
253+
--------
254+
```python
255+
>>> idx_json = IndexJson.from_package_archive(
256+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
257+
... )
258+
>>> idx_json.platform
259+
'linux'
260+
>>>
261+
```
262+
"""
263+
if platform := self._inner.platform:
264+
return platform
265+
266+
return None
267+
268+
@property
269+
def subdir(self) -> Optional[str]:
270+
"""
271+
The subdirectory that contains this package.
272+
273+
Examples
274+
--------
275+
```python
276+
>>> idx_json = IndexJson.from_package_archive(
277+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
278+
... )
279+
>>> idx_json.subdir
280+
'linux-ppc64le'
281+
>>>
282+
```
283+
"""
284+
if subdir := self._inner.subdir:
285+
return subdir
286+
287+
return None
288+
289+
@property
290+
def timestamp(self) -> Optional[int]:
291+
"""
292+
The timestamp when this package was created
293+
294+
Examples
295+
--------
296+
```python
297+
>>> idx_json = IndexJson.from_package_archive(
298+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
299+
... )
300+
>>> idx_json.timestamp
301+
1661200742
302+
>>>
303+
```
304+
"""
305+
if timestamp := self._inner.timestamp:
306+
return timestamp
307+
308+
return None
309+
310+
@property
311+
def track_features(self) -> List[str]:
312+
"""
313+
Track features are nowadays only used to downweight packages (ie. give them less priority). To
314+
that effect, the number of track features is counted (number of commas) and the package is downweighted
315+
by the number of track_features.
316+
317+
Examples
318+
--------
319+
```python
320+
>>> idx_json = IndexJson.from_package_archive(
321+
... "../test-data/with-symlinks/python-3.10.6-h2c4edbf_0_cpython.tar.bz2"
322+
... )
323+
>>> idx_json.track_features
324+
[]
325+
>>>
326+
```
327+
"""
328+
return self._inner.track_features
329+
330+
@classmethod
331+
def _from_py_index_json(cls, py_index_json: PyIndexJson) -> IndexJson:
332+
index_json = cls.__new__(cls)
333+
index_json._inner = py_index_json
334+
335+
return index_json
336+
337+
def __repr__(self) -> str:
338+
"""
339+
Returns a representation of the IndexJson.
340+
"""
341+
return "IndexJson()"

0 commit comments

Comments
 (0)