py-rattler 0.22.0__cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py_rattler-0.22.0.dist-info/METADATA +208 -0
- py_rattler-0.22.0.dist-info/RECORD +68 -0
- py_rattler-0.22.0.dist-info/WHEEL +4 -0
- rattler/__init__.py +114 -0
- rattler/channel/__init__.py +5 -0
- rattler/channel/channel.py +94 -0
- rattler/channel/channel_config.py +43 -0
- rattler/channel/channel_priority.py +14 -0
- rattler/exceptions.py +120 -0
- rattler/explicit_environment/__init__.py +3 -0
- rattler/explicit_environment/environment.py +69 -0
- rattler/index/__init__.py +3 -0
- rattler/index/index.py +112 -0
- rattler/install/__init__.py +3 -0
- rattler/install/installer.py +96 -0
- rattler/lock/__init__.py +23 -0
- rattler/lock/channel.py +52 -0
- rattler/lock/environment.py +213 -0
- rattler/lock/hash.py +33 -0
- rattler/lock/lock_file.py +118 -0
- rattler/lock/package.py +302 -0
- rattler/match_spec/__init__.py +4 -0
- rattler/match_spec/match_spec.py +294 -0
- rattler/match_spec/nameless_match_spec.py +185 -0
- rattler/networking/__init__.py +21 -0
- rattler/networking/client.py +74 -0
- rattler/networking/fetch_repo_data.py +103 -0
- rattler/networking/middleware.py +234 -0
- rattler/package/__init__.py +26 -0
- rattler/package/about_json.py +329 -0
- rattler/package/index_json.py +437 -0
- rattler/package/no_arch_type.py +142 -0
- rattler/package/package_name.py +204 -0
- rattler/package/package_name_matcher.py +81 -0
- rattler/package/paths_json.py +696 -0
- rattler/package/run_exports_json.py +268 -0
- rattler/package_streaming/__init__.py +26 -0
- rattler/platform/__init__.py +4 -0
- rattler/platform/arch.py +59 -0
- rattler/platform/platform.py +217 -0
- rattler/prefix/__init__.py +4 -0
- rattler/prefix/prefix_paths.py +442 -0
- rattler/prefix/prefix_record.py +234 -0
- rattler/pty/__init__.py +25 -0
- rattler/pty/pty_process.py +391 -0
- rattler/pty/pty_session.py +241 -0
- rattler/py.typed +0 -0
- rattler/rattler.abi3.so +0 -0
- rattler/repo_data/__init__.py +19 -0
- rattler/repo_data/gateway.py +337 -0
- rattler/repo_data/package_record.py +938 -0
- rattler/repo_data/patch_instructions.py +22 -0
- rattler/repo_data/record.py +164 -0
- rattler/repo_data/repo_data.py +74 -0
- rattler/repo_data/source.py +85 -0
- rattler/repo_data/sparse.py +356 -0
- rattler/shell/__init__.py +3 -0
- rattler/shell/shell.py +134 -0
- rattler/solver/__init__.py +3 -0
- rattler/solver/solver.py +220 -0
- rattler/utils/rattler_version.py +19 -0
- rattler/version/__init__.py +5 -0
- rattler/version/version.py +591 -0
- rattler/version/version_spec.py +184 -0
- rattler/version/with_source.py +80 -0
- rattler/virtual_package/__init__.py +4 -0
- rattler/virtual_package/generic.py +136 -0
- rattler/virtual_package/virtual_package.py +201 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import os
|
|
3
|
+
from typing import List, TYPE_CHECKING, Literal, Optional
|
|
4
|
+
|
|
5
|
+
from rattler.package.paths_json import FileMode
|
|
6
|
+
from rattler.rattler import PyPrefixPaths, PyPrefixPathsEntry, PyPrefixPathType
|
|
7
|
+
|
|
8
|
+
# `os.PathLike` started to be generic from Python 3.9
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
BasePathLike = os.PathLike[str]
|
|
11
|
+
else:
|
|
12
|
+
BasePathLike = os.PathLike
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PrefixPathType:
|
|
16
|
+
_inner: PyPrefixPathType
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
path_type: Literal[
|
|
21
|
+
"hardlink",
|
|
22
|
+
"softlink",
|
|
23
|
+
"directory",
|
|
24
|
+
"pyc_file",
|
|
25
|
+
"windows_python_entry_point_script",
|
|
26
|
+
"windows_python_entry_point_exe",
|
|
27
|
+
"unix_python_entry_point",
|
|
28
|
+
],
|
|
29
|
+
) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Create a new PrefixPathType instance.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
path_type : str
|
|
36
|
+
The type of path. Must be one of: "hardlink", "softlink", "directory"
|
|
37
|
+
|
|
38
|
+
Examples
|
|
39
|
+
--------
|
|
40
|
+
```python
|
|
41
|
+
>>> path_type = PrefixPathType("hardlink")
|
|
42
|
+
>>> path_type.hardlink
|
|
43
|
+
True
|
|
44
|
+
>>>
|
|
45
|
+
```
|
|
46
|
+
"""
|
|
47
|
+
self._inner = PyPrefixPathType(path_type)
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def from_py_path_type(cls, py_path_type: PyPrefixPathType) -> PrefixPathType:
|
|
51
|
+
"""Construct Rattler PathType from FFI PyPathType object."""
|
|
52
|
+
path_type = cls.__new__(cls)
|
|
53
|
+
path_type._inner = py_path_type
|
|
54
|
+
return path_type
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def hardlink(self) -> bool:
|
|
58
|
+
"""
|
|
59
|
+
Whether the path should be hardlinked (the default) (once installed)
|
|
60
|
+
"""
|
|
61
|
+
return self._inner.hardlink
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def softlink(self) -> bool:
|
|
65
|
+
"""
|
|
66
|
+
Whether the path should be softlinked (once installed)
|
|
67
|
+
"""
|
|
68
|
+
return self._inner.softlink
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def directory(self) -> bool:
|
|
72
|
+
"""
|
|
73
|
+
This is a directory
|
|
74
|
+
"""
|
|
75
|
+
return self._inner.directory
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def pyc_file(self) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
This is a file compiled from Python code when a noarch package was installed
|
|
81
|
+
"""
|
|
82
|
+
return self._inner.pyc_file
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def windows_python_entry_point_script(self) -> bool:
|
|
86
|
+
"""
|
|
87
|
+
A Windows entry point python script (a <entrypoint>-script.py Python script file)
|
|
88
|
+
"""
|
|
89
|
+
return self._inner.windows_python_entry_point_script
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def windows_python_entry_point_exe(self) -> bool:
|
|
93
|
+
"""
|
|
94
|
+
A Windows entry point python script (a <entrypoint>.exe executable)
|
|
95
|
+
"""
|
|
96
|
+
return self._inner.windows_python_entry_point_exe
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def unix_python_entry_point(self) -> bool:
|
|
100
|
+
"""
|
|
101
|
+
A Unix entry point python script (a <entrypoint> Python script file)
|
|
102
|
+
"""
|
|
103
|
+
return self._inner.unix_python_entry_point
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class PrefixPathsEntry(BasePathLike):
|
|
107
|
+
_inner: PyPrefixPathsEntry
|
|
108
|
+
|
|
109
|
+
def __init__(
|
|
110
|
+
self,
|
|
111
|
+
relative_path: os.PathLike[str],
|
|
112
|
+
path_type: PrefixPathType,
|
|
113
|
+
prefix_placeholder: Optional[str] = None,
|
|
114
|
+
file_mode: Optional[FileMode] = None,
|
|
115
|
+
sha256: Optional[bytes] = None,
|
|
116
|
+
sha256_in_prefix: Optional[bytes] = None,
|
|
117
|
+
size_in_bytes: Optional[int] = None,
|
|
118
|
+
original_path: Optional[os.PathLike[str]] = None,
|
|
119
|
+
) -> None:
|
|
120
|
+
"""
|
|
121
|
+
Create a new PrefixPathsEntry instance.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
relative_path : os.PathLike[str]
|
|
126
|
+
The relative path from the root of the package
|
|
127
|
+
path_type : PrefixPathType
|
|
128
|
+
Determines how to include the file when installing the package
|
|
129
|
+
prefix_placeholder : Optional[str], optional
|
|
130
|
+
The placeholder prefix used in the file, by default None
|
|
131
|
+
file_mode : Optional[FileMode], optional
|
|
132
|
+
The file mode of the path, by default None
|
|
133
|
+
sha256 : Optional[bytes], optional
|
|
134
|
+
The sha256 of the path, by default None
|
|
135
|
+
sha256_in_prefix : Optional[bytes], optional
|
|
136
|
+
The sha256 of the path in the prefix, by default None
|
|
137
|
+
size_in_bytes : Optional[int], optional
|
|
138
|
+
The size of the path in bytes, by default None
|
|
139
|
+
original_path : Optional[os.PathLike[str]], optional
|
|
140
|
+
The original path of the file, by default None
|
|
141
|
+
"""
|
|
142
|
+
self._inner = PyPrefixPathsEntry(
|
|
143
|
+
relative_path,
|
|
144
|
+
path_type._inner,
|
|
145
|
+
prefix_placeholder,
|
|
146
|
+
file_mode._inner if file_mode else None,
|
|
147
|
+
sha256,
|
|
148
|
+
sha256_in_prefix,
|
|
149
|
+
size_in_bytes,
|
|
150
|
+
original_path,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
def __fspath__(self) -> str:
|
|
154
|
+
return str(self._inner.path)
|
|
155
|
+
|
|
156
|
+
@classmethod
|
|
157
|
+
def _from_py_paths_entry(cls, py_paths_entry: PyPrefixPathsEntry) -> PrefixPathsEntry:
|
|
158
|
+
"""Construct Rattler PathsEntry from FFI PyPathsEntry object."""
|
|
159
|
+
entry = cls.__new__(cls)
|
|
160
|
+
entry._inner = py_paths_entry
|
|
161
|
+
return entry
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def relative_path(self) -> os.PathLike[str]:
|
|
165
|
+
"""
|
|
166
|
+
The relative path of the entry.
|
|
167
|
+
|
|
168
|
+
Examples
|
|
169
|
+
--------
|
|
170
|
+
```python
|
|
171
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
172
|
+
>>> r = PrefixRecord.from_path(
|
|
173
|
+
... "../test-data/conda-meta/tk-8.6.12-h8ffe710_0.json"
|
|
174
|
+
... )
|
|
175
|
+
>>> paths = r.paths_data
|
|
176
|
+
>>> relative_path = paths.paths[0].relative_path
|
|
177
|
+
>>>
|
|
178
|
+
...
|
|
179
|
+
```
|
|
180
|
+
"""
|
|
181
|
+
return self._inner.relative_path
|
|
182
|
+
|
|
183
|
+
@relative_path.setter
|
|
184
|
+
def relative_path(self, path: os.PathLike[str]) -> None:
|
|
185
|
+
self._inner.set_relative_path(path)
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def no_link(self) -> bool:
|
|
189
|
+
"""
|
|
190
|
+
Whether this file should be linked
|
|
191
|
+
|
|
192
|
+
Examples
|
|
193
|
+
--------
|
|
194
|
+
```python
|
|
195
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
196
|
+
>>> r = PrefixRecord.from_path(
|
|
197
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
198
|
+
... )
|
|
199
|
+
>>> paths = r.paths_data
|
|
200
|
+
>>> no_link = paths.paths[0].no_link
|
|
201
|
+
>>>
|
|
202
|
+
```
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
@no_link.setter
|
|
206
|
+
def no_link(self, no_link: bool) -> None:
|
|
207
|
+
self._inner.set_no_link(no_link)
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def path_type(self) -> PrefixPathType:
|
|
211
|
+
"""
|
|
212
|
+
The type of the path.
|
|
213
|
+
|
|
214
|
+
Examples
|
|
215
|
+
--------
|
|
216
|
+
```python
|
|
217
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
218
|
+
>>> r = PrefixRecord.from_path(
|
|
219
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
220
|
+
... )
|
|
221
|
+
>>> paths = r.paths_data
|
|
222
|
+
>>> path_type = paths.paths[0].path_type
|
|
223
|
+
>>>
|
|
224
|
+
```
|
|
225
|
+
"""
|
|
226
|
+
return PrefixPathType.from_py_path_type(self._inner.path_type)
|
|
227
|
+
|
|
228
|
+
@path_type.setter
|
|
229
|
+
def path_type(self, path_type: PrefixPathType) -> None:
|
|
230
|
+
self._inner.set_path_type(path_type._inner)
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def prefix_placeholder(self) -> str | None:
|
|
234
|
+
"""
|
|
235
|
+
The prefix placeholder for the path.
|
|
236
|
+
|
|
237
|
+
Examples
|
|
238
|
+
--------
|
|
239
|
+
```python
|
|
240
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
241
|
+
>>> r = PrefixRecord.from_path(
|
|
242
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
243
|
+
... )
|
|
244
|
+
>>> paths = r.paths_data
|
|
245
|
+
>>> prefix_placeholder = paths.paths[0].prefix_placeholder
|
|
246
|
+
>>>
|
|
247
|
+
```
|
|
248
|
+
"""
|
|
249
|
+
return self._inner.prefix_placeholder
|
|
250
|
+
|
|
251
|
+
@prefix_placeholder.setter
|
|
252
|
+
def prefix_placeholder(self, placeholder: Optional[str]) -> None:
|
|
253
|
+
self._inner.set_prefix_placeholder(placeholder)
|
|
254
|
+
|
|
255
|
+
@property
|
|
256
|
+
def file_mode(self) -> FileMode:
|
|
257
|
+
"""
|
|
258
|
+
The file mode of the path.
|
|
259
|
+
|
|
260
|
+
Examples
|
|
261
|
+
--------
|
|
262
|
+
```python
|
|
263
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
264
|
+
>>> r = PrefixRecord.from_path(
|
|
265
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
266
|
+
... )
|
|
267
|
+
>>> paths = r.paths_data
|
|
268
|
+
>>> file_mode = paths.paths[0].file_mode
|
|
269
|
+
>>>
|
|
270
|
+
```
|
|
271
|
+
"""
|
|
272
|
+
return FileMode._from_py_file_mode(self._inner.file_mode)
|
|
273
|
+
|
|
274
|
+
@file_mode.setter
|
|
275
|
+
def file_mode(self, file_mode: Optional[FileMode]) -> None:
|
|
276
|
+
self._inner.set_file_mode(file_mode._inner if file_mode else None)
|
|
277
|
+
|
|
278
|
+
@property
|
|
279
|
+
def sha256(self) -> bytes:
|
|
280
|
+
"""
|
|
281
|
+
The sha256 of the path.
|
|
282
|
+
|
|
283
|
+
Examples
|
|
284
|
+
--------
|
|
285
|
+
```python
|
|
286
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
287
|
+
>>> r = PrefixRecord.from_path(
|
|
288
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
289
|
+
... )
|
|
290
|
+
>>> paths = r.paths_data
|
|
291
|
+
>>> sha256 = paths.paths[0].sha256
|
|
292
|
+
>>>
|
|
293
|
+
```
|
|
294
|
+
"""
|
|
295
|
+
return self._inner.sha256
|
|
296
|
+
|
|
297
|
+
@sha256.setter
|
|
298
|
+
def sha256(self, sha256: Optional[bytes]) -> None:
|
|
299
|
+
self._inner.set_sha256(sha256)
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def sha256_in_prefix(self) -> bytes:
|
|
303
|
+
"""
|
|
304
|
+
The sha256 of the path in the prefix.
|
|
305
|
+
|
|
306
|
+
Examples
|
|
307
|
+
--------
|
|
308
|
+
```python
|
|
309
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
310
|
+
>>> r = PrefixRecord.from_path(
|
|
311
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
312
|
+
... )
|
|
313
|
+
>>> paths = r.paths_data
|
|
314
|
+
>>> sha256_in_prefix = paths.paths[0].sha256_in_prefix
|
|
315
|
+
>>>
|
|
316
|
+
```
|
|
317
|
+
"""
|
|
318
|
+
return self._inner.sha256_in_prefix
|
|
319
|
+
|
|
320
|
+
@sha256_in_prefix.setter
|
|
321
|
+
def sha256_in_prefix(self, sha256: Optional[bytes]) -> None:
|
|
322
|
+
self._inner.set_sha256_in_prefix(sha256)
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def size_in_bytes(self) -> int:
|
|
326
|
+
"""
|
|
327
|
+
The size of the path in bytes.
|
|
328
|
+
|
|
329
|
+
Examples
|
|
330
|
+
--------
|
|
331
|
+
```python
|
|
332
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
333
|
+
>>> r = PrefixRecord.from_path(
|
|
334
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
335
|
+
... )
|
|
336
|
+
>>> paths = r.paths_data
|
|
337
|
+
>>> size_in_bytes = paths.paths[0].size_in_bytes
|
|
338
|
+
>>>
|
|
339
|
+
```
|
|
340
|
+
"""
|
|
341
|
+
return self._inner.size_in_bytes
|
|
342
|
+
|
|
343
|
+
@size_in_bytes.setter
|
|
344
|
+
def size_in_bytes(self, size: Optional[int]) -> None:
|
|
345
|
+
self._inner.set_size_in_bytes(size)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class PrefixPaths:
|
|
349
|
+
_paths: PyPrefixPaths
|
|
350
|
+
|
|
351
|
+
@classmethod
|
|
352
|
+
def _from_py_prefix_paths(cls, py_prefix_paths: PyPrefixPaths) -> PrefixPaths:
|
|
353
|
+
"""Construct Rattler PrefixRecord from FFI PyPrefixRecord object."""
|
|
354
|
+
paths = cls.__new__(cls)
|
|
355
|
+
paths._paths = py_prefix_paths
|
|
356
|
+
return paths
|
|
357
|
+
|
|
358
|
+
def __init__(self, paths_version: int = 1) -> None:
|
|
359
|
+
"""
|
|
360
|
+
Create a new PrefixPaths instance.
|
|
361
|
+
|
|
362
|
+
Parameters
|
|
363
|
+
----------
|
|
364
|
+
paths_version : int, optional
|
|
365
|
+
The version of the paths file format, by default 1
|
|
366
|
+
|
|
367
|
+
Examples
|
|
368
|
+
--------
|
|
369
|
+
```python
|
|
370
|
+
>>> paths = PrefixPaths()
|
|
371
|
+
>>> paths.paths_version
|
|
372
|
+
1
|
|
373
|
+
>>>
|
|
374
|
+
```
|
|
375
|
+
"""
|
|
376
|
+
self._paths = PyPrefixPaths(paths_version)
|
|
377
|
+
|
|
378
|
+
@property
|
|
379
|
+
def paths_version(self) -> int:
|
|
380
|
+
"""
|
|
381
|
+
The version of the file.
|
|
382
|
+
|
|
383
|
+
Examples
|
|
384
|
+
--------
|
|
385
|
+
```python
|
|
386
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
387
|
+
>>> r = PrefixRecord.from_path(
|
|
388
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
389
|
+
... )
|
|
390
|
+
>>> paths = r.paths_data
|
|
391
|
+
>>> paths.paths_version
|
|
392
|
+
1
|
|
393
|
+
>>>
|
|
394
|
+
```
|
|
395
|
+
"""
|
|
396
|
+
return self._paths.paths_version
|
|
397
|
+
|
|
398
|
+
@paths_version.setter
|
|
399
|
+
def paths_version(self, version: int) -> None:
|
|
400
|
+
self._paths.paths_version = version
|
|
401
|
+
|
|
402
|
+
@property
|
|
403
|
+
def paths(self) -> List[PrefixPathsEntry]:
|
|
404
|
+
"""
|
|
405
|
+
All entries included in the package.
|
|
406
|
+
|
|
407
|
+
Examples
|
|
408
|
+
--------
|
|
409
|
+
```python
|
|
410
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
411
|
+
>>> r = PrefixRecord.from_path(
|
|
412
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
413
|
+
... )
|
|
414
|
+
>>> paths = r.paths_data
|
|
415
|
+
>>> paths.paths # doctest:+ELLIPSIS
|
|
416
|
+
[...]
|
|
417
|
+
>>>
|
|
418
|
+
```
|
|
419
|
+
"""
|
|
420
|
+
return [PrefixPathsEntry._from_py_paths_entry(path) for path in self._paths.paths]
|
|
421
|
+
|
|
422
|
+
@paths.setter
|
|
423
|
+
def paths(self, paths: List[PrefixPathsEntry]) -> None:
|
|
424
|
+
self._paths.paths = [path._inner for path in paths]
|
|
425
|
+
|
|
426
|
+
def __repr__(self) -> str:
|
|
427
|
+
"""
|
|
428
|
+
Returns a representation of the PrefixPaths.
|
|
429
|
+
|
|
430
|
+
Examples
|
|
431
|
+
--------
|
|
432
|
+
```python
|
|
433
|
+
>>> from rattler.prefix.prefix_record import PrefixRecord
|
|
434
|
+
>>> r = PrefixRecord.from_path(
|
|
435
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
436
|
+
... )
|
|
437
|
+
>>> r.paths_data # doctest:+ELLIPSIS
|
|
438
|
+
PrefixPaths(paths=[...])
|
|
439
|
+
>>>
|
|
440
|
+
```
|
|
441
|
+
"""
|
|
442
|
+
return f"PrefixPaths(paths={self.paths})"
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import os
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import List, Optional
|
|
5
|
+
|
|
6
|
+
from rattler.rattler import PyRecord, PyLink
|
|
7
|
+
from rattler.prefix.prefix_paths import PrefixPaths
|
|
8
|
+
from rattler.repo_data.record import RepoDataRecord
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LinkType(Enum):
|
|
13
|
+
HARDLINK = ("hardlink",)
|
|
14
|
+
COPY = ("copy",)
|
|
15
|
+
SOFTLINK = ("softlink",)
|
|
16
|
+
DIRECTORY = ("directory",)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Link:
|
|
20
|
+
_inner: PyLink
|
|
21
|
+
|
|
22
|
+
def __init__(self, path: os.PathLike[str], type: Optional[LinkType]) -> None:
|
|
23
|
+
self._inner = PyLink(path, type.value if type else None)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class PrefixRecord(RepoDataRecord):
|
|
27
|
+
@classmethod
|
|
28
|
+
def _from_py_record(cls, py_record: PyRecord) -> PrefixRecord:
|
|
29
|
+
"""Construct Rattler PrefixRecord from FFI PyRecord object."""
|
|
30
|
+
|
|
31
|
+
# quick sanity check
|
|
32
|
+
assert py_record.is_prefix_record
|
|
33
|
+
record = cls.__new__(cls)
|
|
34
|
+
record._record = py_record
|
|
35
|
+
return record
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
repodata_record: RepoDataRecord,
|
|
40
|
+
paths_data: PrefixPaths,
|
|
41
|
+
link: Optional[Link] = None,
|
|
42
|
+
package_tarball_full_path: Optional[os.PathLike[str]] = None,
|
|
43
|
+
extracted_package_dir: Optional[os.PathLike[str]] = None,
|
|
44
|
+
requested_spec: Optional[str] = None,
|
|
45
|
+
requested_specs: Optional[List[str]] = None,
|
|
46
|
+
files: Optional[List[os.PathLike[str]]] = None,
|
|
47
|
+
) -> None:
|
|
48
|
+
record = PyRecord.create_prefix_record(
|
|
49
|
+
repodata_record=repodata_record._record,
|
|
50
|
+
paths_data=paths_data._paths,
|
|
51
|
+
link=link._inner if link else None,
|
|
52
|
+
package_tarball_full_path=package_tarball_full_path,
|
|
53
|
+
extracted_package_dir=extracted_package_dir,
|
|
54
|
+
files=files,
|
|
55
|
+
requested_spec=requested_spec,
|
|
56
|
+
requested_specs=requested_specs,
|
|
57
|
+
)
|
|
58
|
+
self._record = record
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def from_path(path: os.PathLike[str]) -> PrefixRecord:
|
|
62
|
+
"""
|
|
63
|
+
Parses a PrefixRecord from a file.
|
|
64
|
+
|
|
65
|
+
Examples
|
|
66
|
+
--------
|
|
67
|
+
```python
|
|
68
|
+
>>> r = PrefixRecord.from_path(
|
|
69
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
70
|
+
... )
|
|
71
|
+
>>> assert isinstance(r, PrefixRecord)
|
|
72
|
+
>>>
|
|
73
|
+
```
|
|
74
|
+
"""
|
|
75
|
+
return PrefixRecord._from_py_record(PyRecord.from_path(path))
|
|
76
|
+
|
|
77
|
+
def write_to_path(self, path: os.PathLike[str], pretty: bool) -> None:
|
|
78
|
+
"""
|
|
79
|
+
Writes the contents of this instance to the file at the specified location.
|
|
80
|
+
"""
|
|
81
|
+
self._record.write_to_path(path, pretty)
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def package_tarball_full_path(self) -> Optional[Path]:
|
|
85
|
+
"""
|
|
86
|
+
The path to where the archive of the package was stored on disk.
|
|
87
|
+
|
|
88
|
+
Examples
|
|
89
|
+
--------
|
|
90
|
+
```python
|
|
91
|
+
>>> r = PrefixRecord.from_path(
|
|
92
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
93
|
+
... )
|
|
94
|
+
>>> str(r.package_tarball_full_path)
|
|
95
|
+
'C:\\\\Users\\\\bas\\\\micromamba\\\\pkgs\\\\requests-2.28.2-pyhd8ed1ab_0.tar.bz2'
|
|
96
|
+
>>>
|
|
97
|
+
```
|
|
98
|
+
"""
|
|
99
|
+
return self._record.package_tarball_full_path
|
|
100
|
+
|
|
101
|
+
@package_tarball_full_path.setter
|
|
102
|
+
def package_tarball_full_path(self, value: Optional[os.PathLike[str]]) -> None:
|
|
103
|
+
self._record.package_tarball_full_path = value
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def extracted_package_dir(self) -> Optional[Path]:
|
|
107
|
+
"""
|
|
108
|
+
The path that contains the extracted package content.
|
|
109
|
+
|
|
110
|
+
Examples
|
|
111
|
+
--------
|
|
112
|
+
```python
|
|
113
|
+
>>> r = PrefixRecord.from_path(
|
|
114
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
115
|
+
... )
|
|
116
|
+
>>> str(r.extracted_package_dir)
|
|
117
|
+
'C:\\\\Users\\\\bas\\\\micromamba\\\\pkgs\\\\requests-2.28.2-pyhd8ed1ab_0'
|
|
118
|
+
>>>
|
|
119
|
+
```
|
|
120
|
+
"""
|
|
121
|
+
return self._record.extracted_package_dir
|
|
122
|
+
|
|
123
|
+
@extracted_package_dir.setter
|
|
124
|
+
def extracted_package_dir(self, value: Optional[os.PathLike[str]]) -> None:
|
|
125
|
+
self._record.extracted_package_dir = value
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def files(self) -> List[Path]:
|
|
129
|
+
"""
|
|
130
|
+
A sorted list of all files included in this package
|
|
131
|
+
|
|
132
|
+
Examples
|
|
133
|
+
--------
|
|
134
|
+
```python
|
|
135
|
+
>>> r = PrefixRecord.from_path(
|
|
136
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
137
|
+
... )
|
|
138
|
+
>>> r.files # doctest:+ELLIPSIS
|
|
139
|
+
[...]
|
|
140
|
+
>>>
|
|
141
|
+
```
|
|
142
|
+
"""
|
|
143
|
+
return self._record.files
|
|
144
|
+
|
|
145
|
+
@files.setter
|
|
146
|
+
def files(self, value: List[os.PathLike[str]]) -> None:
|
|
147
|
+
self._record.files = value
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def paths_data(self) -> PrefixPaths:
|
|
151
|
+
"""
|
|
152
|
+
Information about how files have been linked when installing the package.
|
|
153
|
+
|
|
154
|
+
Examples
|
|
155
|
+
--------
|
|
156
|
+
```python
|
|
157
|
+
>>> r = PrefixRecord.from_path(
|
|
158
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
159
|
+
... )
|
|
160
|
+
>>> r.paths_data # doctest:+ELLIPSIS
|
|
161
|
+
PrefixPaths(paths=[...])
|
|
162
|
+
>>>
|
|
163
|
+
```
|
|
164
|
+
"""
|
|
165
|
+
return PrefixPaths._from_py_prefix_paths(self._record.paths_data)
|
|
166
|
+
|
|
167
|
+
@paths_data.setter
|
|
168
|
+
def paths_data(self, value: PrefixPaths) -> None:
|
|
169
|
+
self._record.paths_data = value._paths
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def requested_spec(self) -> Optional[str]:
|
|
173
|
+
"""
|
|
174
|
+
The spec that was used when this package was installed (deprecated).
|
|
175
|
+
Use requested_specs instead.
|
|
176
|
+
|
|
177
|
+
Examples
|
|
178
|
+
--------
|
|
179
|
+
```python
|
|
180
|
+
>>> r = PrefixRecord.from_path(
|
|
181
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
182
|
+
... )
|
|
183
|
+
>>> r.requested_spec is None
|
|
184
|
+
True
|
|
185
|
+
>>>
|
|
186
|
+
```
|
|
187
|
+
"""
|
|
188
|
+
return self._record.requested_spec
|
|
189
|
+
|
|
190
|
+
@requested_spec.setter
|
|
191
|
+
def requested_spec(self, value: Optional[str]) -> None:
|
|
192
|
+
self._record.requested_spec = value
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def requested_specs(self) -> List[str]:
|
|
196
|
+
"""
|
|
197
|
+
The specs that were used when this package was installed.
|
|
198
|
+
If this package was not directly requested by the user but was instead
|
|
199
|
+
installed as a dependency of another package an empty list will be
|
|
200
|
+
returned.
|
|
201
|
+
|
|
202
|
+
Examples
|
|
203
|
+
--------
|
|
204
|
+
```python
|
|
205
|
+
>>> r = PrefixRecord.from_path(
|
|
206
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
207
|
+
... )
|
|
208
|
+
>>> r.requested_specs
|
|
209
|
+
[]
|
|
210
|
+
>>>
|
|
211
|
+
```
|
|
212
|
+
"""
|
|
213
|
+
return self._record.requested_specs
|
|
214
|
+
|
|
215
|
+
@requested_specs.setter
|
|
216
|
+
def requested_specs(self, value: List[str]) -> None:
|
|
217
|
+
self._record.requested_specs = value
|
|
218
|
+
|
|
219
|
+
def __repr__(self) -> str:
|
|
220
|
+
"""
|
|
221
|
+
Returns a representation of the version
|
|
222
|
+
|
|
223
|
+
Examples
|
|
224
|
+
--------
|
|
225
|
+
```python
|
|
226
|
+
>>> r = PrefixRecord.from_path(
|
|
227
|
+
... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
|
|
228
|
+
... )
|
|
229
|
+
>>> r
|
|
230
|
+
PrefixRecord(name="requests", version="2.28.2")
|
|
231
|
+
>>>
|
|
232
|
+
```
|
|
233
|
+
"""
|
|
234
|
+
return f'PrefixRecord(name="{self.name.normalized}", version="{self.version}")'
|
rattler/pty/__init__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PTY (pseudoterminal) support for interactive shell sessions.
|
|
3
|
+
|
|
4
|
+
This module provides Python bindings to rattler_pty, allowing you to:
|
|
5
|
+
- Create interactive shell sessions in a PTY
|
|
6
|
+
- Send commands programmatically
|
|
7
|
+
- Hand over control to the user with interact()
|
|
8
|
+
- Manage process lifecycle
|
|
9
|
+
|
|
10
|
+
Note: PTY functionality is only available on Unix platforms (Linux, macOS).
|
|
11
|
+
On Windows or when the pty feature is not compiled, importing from this
|
|
12
|
+
module will raise an ImportError.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from rattler.pty.pty_process import PtyProcess, PtyProcessOptions
|
|
19
|
+
from rattler.pty.pty_session import PtySession
|
|
20
|
+
|
|
21
|
+
_PTY_AVAILABLE = True
|
|
22
|
+
__all__ = ["PtyProcess", "PtyProcessOptions", "PtySession"]
|
|
23
|
+
except ImportError:
|
|
24
|
+
_PTY_AVAILABLE = False
|
|
25
|
+
__all__ = []
|