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.
Files changed (68) hide show
  1. py_rattler-0.22.0.dist-info/METADATA +208 -0
  2. py_rattler-0.22.0.dist-info/RECORD +68 -0
  3. py_rattler-0.22.0.dist-info/WHEEL +4 -0
  4. rattler/__init__.py +114 -0
  5. rattler/channel/__init__.py +5 -0
  6. rattler/channel/channel.py +94 -0
  7. rattler/channel/channel_config.py +43 -0
  8. rattler/channel/channel_priority.py +14 -0
  9. rattler/exceptions.py +120 -0
  10. rattler/explicit_environment/__init__.py +3 -0
  11. rattler/explicit_environment/environment.py +69 -0
  12. rattler/index/__init__.py +3 -0
  13. rattler/index/index.py +112 -0
  14. rattler/install/__init__.py +3 -0
  15. rattler/install/installer.py +96 -0
  16. rattler/lock/__init__.py +23 -0
  17. rattler/lock/channel.py +52 -0
  18. rattler/lock/environment.py +213 -0
  19. rattler/lock/hash.py +33 -0
  20. rattler/lock/lock_file.py +118 -0
  21. rattler/lock/package.py +302 -0
  22. rattler/match_spec/__init__.py +4 -0
  23. rattler/match_spec/match_spec.py +294 -0
  24. rattler/match_spec/nameless_match_spec.py +185 -0
  25. rattler/networking/__init__.py +21 -0
  26. rattler/networking/client.py +74 -0
  27. rattler/networking/fetch_repo_data.py +103 -0
  28. rattler/networking/middleware.py +234 -0
  29. rattler/package/__init__.py +26 -0
  30. rattler/package/about_json.py +329 -0
  31. rattler/package/index_json.py +437 -0
  32. rattler/package/no_arch_type.py +142 -0
  33. rattler/package/package_name.py +204 -0
  34. rattler/package/package_name_matcher.py +81 -0
  35. rattler/package/paths_json.py +696 -0
  36. rattler/package/run_exports_json.py +268 -0
  37. rattler/package_streaming/__init__.py +26 -0
  38. rattler/platform/__init__.py +4 -0
  39. rattler/platform/arch.py +59 -0
  40. rattler/platform/platform.py +217 -0
  41. rattler/prefix/__init__.py +4 -0
  42. rattler/prefix/prefix_paths.py +442 -0
  43. rattler/prefix/prefix_record.py +234 -0
  44. rattler/pty/__init__.py +25 -0
  45. rattler/pty/pty_process.py +391 -0
  46. rattler/pty/pty_session.py +241 -0
  47. rattler/py.typed +0 -0
  48. rattler/rattler.abi3.so +0 -0
  49. rattler/repo_data/__init__.py +19 -0
  50. rattler/repo_data/gateway.py +337 -0
  51. rattler/repo_data/package_record.py +938 -0
  52. rattler/repo_data/patch_instructions.py +22 -0
  53. rattler/repo_data/record.py +164 -0
  54. rattler/repo_data/repo_data.py +74 -0
  55. rattler/repo_data/source.py +85 -0
  56. rattler/repo_data/sparse.py +356 -0
  57. rattler/shell/__init__.py +3 -0
  58. rattler/shell/shell.py +134 -0
  59. rattler/solver/__init__.py +3 -0
  60. rattler/solver/solver.py +220 -0
  61. rattler/utils/rattler_version.py +19 -0
  62. rattler/version/__init__.py +5 -0
  63. rattler/version/version.py +591 -0
  64. rattler/version/version_spec.py +184 -0
  65. rattler/version/with_source.py +80 -0
  66. rattler/virtual_package/__init__.py +4 -0
  67. rattler/virtual_package/generic.py +136 -0
  68. rattler/virtual_package/virtual_package.py +201 -0
@@ -0,0 +1,3 @@
1
+ from rattler.shell.shell import ActivationVariables, activate, Shell, PathModificationBehavior
2
+
3
+ __all__ = ["ActivationVariables", "activate", "Shell", "PathModificationBehavior"]
rattler/shell/shell.py ADDED
@@ -0,0 +1,134 @@
1
+ from __future__ import annotations
2
+ from enum import Enum
3
+
4
+ from typing import Iterable, Optional
5
+ from pathlib import Path
6
+ import os
7
+ from rattler.platform.platform import Platform, PlatformLiteral
8
+
9
+ from rattler.rattler import (
10
+ PyActivationVariables,
11
+ PyActivator,
12
+ PyShellEnum,
13
+ PyActivationResult,
14
+ )
15
+
16
+
17
+ class PathModificationBehavior(Enum):
18
+ """
19
+ The behavior to use when modifying the PATH environment variable.
20
+ Prepend will add the new path to the beginning of the PATH variable.
21
+ Append will add the new path to the end of the PATH variable.
22
+ Replace will replace the entire PATH variable with the new path.
23
+ """
24
+
25
+ Prepend = "prepend"
26
+ Append = "append"
27
+ Replace = "replace"
28
+
29
+
30
+ class ActivationVariables:
31
+ """An object that holds the state of the current environment."""
32
+
33
+ def __init__(
34
+ self,
35
+ current_prefix: Optional[os.PathLike[str]] = None,
36
+ current_path: Optional[Iterable[str] | Iterable[os.PathLike[str]]] | None = None,
37
+ path_modification_behavior: PathModificationBehavior = PathModificationBehavior.Prepend,
38
+ ) -> None:
39
+ """
40
+ Construct a new ActivationVariables object.
41
+
42
+ current_prefix: The current activated conda prefix (usually
43
+ `os.environ["CONDA_PREFIX"]`). This prefix is going to be deactivated.
44
+ current_path: The current PATH environment variable (usually
45
+ `os.environ["PATH"].split(os.pathsep)`).
46
+ path_modification_behavior: The behavior to use when modifying the PATH
47
+ environment variable. One of "Prepend", "Append", or "Replace".
48
+ Defaults to "Prepend".
49
+ """
50
+ self._activation_variables = PyActivationVariables(
51
+ current_prefix,
52
+ current_path or os.environ.get("PATH", "").split(os.pathsep),
53
+ path_modification_behavior.value,
54
+ )
55
+
56
+ def __str__(self) -> str:
57
+ return self._activation_variables.as_str()
58
+
59
+
60
+ class ActivationResult:
61
+ """An object that holds the result of activating a conda environment."""
62
+
63
+ _py_activation_result: PyActivationResult
64
+
65
+ @classmethod
66
+ def _from_py_activation_result(cls, py_activation_result: PyActivationResult) -> ActivationResult:
67
+ """Construct Rattler version from FFI PyActivationResult object."""
68
+ activation_result = cls.__new__(cls)
69
+ activation_result._py_activation_result = py_activation_result
70
+ return activation_result
71
+
72
+ @property
73
+ def path(self) -> Path:
74
+ """The new PATH environment variable."""
75
+ return self._py_activation_result.path
76
+
77
+ @property
78
+ def script(self) -> str:
79
+ """The script to run to activate the environment."""
80
+ return self._py_activation_result.script
81
+
82
+
83
+ class Shell:
84
+ """An enum of supported shells."""
85
+
86
+ bash = PyShellEnum.Bash
87
+ zsh = PyShellEnum.Zsh
88
+ fish = PyShellEnum.Fish
89
+ xonsh = PyShellEnum.Xonsh
90
+ powershell = PyShellEnum.PowerShell
91
+ cmd_exe = PyShellEnum.CmdExe
92
+
93
+
94
+ def activate(
95
+ prefix: Path,
96
+ activation_variables: ActivationVariables,
97
+ shell: Optional[Shell] = None,
98
+ platform: Optional[Platform | PlatformLiteral] = None,
99
+ ) -> ActivationResult:
100
+ """
101
+ Return an ActivationResult object that contains the new PATH environment variable
102
+ and the script to run to activate the environment.
103
+
104
+ Arguments:
105
+ prefix: The path to the conda prefix to activate.
106
+ activation_variables: The current activation variables.
107
+ shell: The shell to generate the activation script for.
108
+ platform: The platform to generate the activation script for.
109
+ If None, the current platform is used.
110
+
111
+ Returns:
112
+ An ActivationResult object containing the new PATH environment variable
113
+ and the script to run to activate the environment.
114
+
115
+ Examples
116
+ --------
117
+ ```python
118
+ >>> from rattler.shell import Shell, activate, ActivationVariables
119
+ >>> from rattler.platform import Platform
120
+ >>> from pathlib import Path
121
+ >>> import sys
122
+ >>> p = Path("/path/to/conda/prefix")
123
+ >>> actvars = ActivationVariables()
124
+ >>> a = activate(p, actvars, Shell.xonsh)
125
+ >>> print(a)
126
+ <rattler.shell.shell.ActivationResult object at ...>
127
+ >>>
128
+ ```
129
+ """
130
+ platform = Platform(platform) if isinstance(platform, str) else platform or Platform.current()
131
+ shell = shell or Shell.bash
132
+ return ActivationResult._from_py_activation_result(
133
+ PyActivator.activate(prefix, activation_variables._activation_variables, platform._inner, shell)
134
+ )
@@ -0,0 +1,3 @@
1
+ from rattler.solver.solver import solve, solve_with_sparse_repodata
2
+
3
+ __all__ = ["solve", "solve_with_sparse_repodata"]
@@ -0,0 +1,220 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from typing import TYPE_CHECKING, List, Literal, Optional, Sequence, Union
5
+
6
+ from rattler.channel.channel import Channel
7
+ from rattler.channel.channel_priority import ChannelPriority
8
+ from rattler.match_spec.match_spec import MatchSpec
9
+ from rattler.platform.platform import Platform, PlatformLiteral
10
+ from rattler.rattler import PyMatchSpec, py_solve, py_solve_with_sparse_repodata
11
+ from rattler.repo_data.gateway import Gateway, _convert_sources
12
+ from rattler.repo_data.record import RepoDataRecord
13
+ from rattler.repo_data.sparse import SparseRepoData, PackageFormatSelection
14
+ from rattler.virtual_package.generic import GenericVirtualPackage
15
+ from rattler.virtual_package.virtual_package import VirtualPackage
16
+
17
+ if TYPE_CHECKING:
18
+ from rattler.repo_data.source import RepoDataSource
19
+
20
+ SolveStrategy = Literal["highest", "lowest", "lowest-direct"]
21
+ """Defines the strategy to use when multiple versions of a package are available during solving."""
22
+
23
+
24
+ async def solve(
25
+ sources: Sequence[Union[Channel, str, RepoDataSource]],
26
+ specs: Sequence[MatchSpec | str],
27
+ gateway: Gateway = Gateway(),
28
+ platforms: Optional[Sequence[Platform | PlatformLiteral]] = None,
29
+ locked_packages: Optional[Sequence[RepoDataRecord]] = None,
30
+ pinned_packages: Optional[Sequence[RepoDataRecord]] = None,
31
+ virtual_packages: Optional[Sequence[GenericVirtualPackage | VirtualPackage]] = None,
32
+ timeout: Optional[datetime.timedelta] = None,
33
+ channel_priority: ChannelPriority = ChannelPriority.Strict,
34
+ exclude_newer: Optional[datetime.datetime] = None,
35
+ strategy: SolveStrategy = "highest",
36
+ constraints: Optional[Sequence[MatchSpec | str]] = None,
37
+ ) -> List[RepoDataRecord]:
38
+ """
39
+ Resolve the dependencies and return the `RepoDataRecord`s
40
+ that should be present in the environment.
41
+
42
+ Arguments:
43
+ sources: The sources to query for the packages. Can be channels (by name, URL,
44
+ or Channel object) or custom RepoDataSource implementations.
45
+ specs: A list of matchspec to solve.
46
+ platforms: The platforms to query for the packages. If `None` the current platform and
47
+ `noarch` is used.
48
+ gateway: The gateway to use for acquiring repodata.
49
+ locked_packages: Records of packages that are previously selected.
50
+ If the solver encounters multiple variants of a single
51
+ package (identified by its name), it will sort the records
52
+ and select the best possible version. However, if there
53
+ exists a locked version it will prefer that variant instead.
54
+ This is useful to reduce the number of packages that are
55
+ updated when installing new packages. Usually you add the
56
+ currently installed packages or packages from a lock-file here.
57
+ pinned_packages: Records of packages that are previously selected and CANNOT
58
+ be changed. If the solver encounters multiple variants of
59
+ a single package (identified by its name), it will sort the
60
+ records and select the best possible version. However, if
61
+ there is a variant available in the `pinned_packages` field it
62
+ will always select that version no matter what even if that
63
+ means other packages have to be downgraded.
64
+ virtual_packages: A list of virtual packages considered active.
65
+ channel_priority: (Default = ChannelPriority.Strict) When `ChannelPriority.Strict`
66
+ the channel that the package is first found in will be used as
67
+ the only channel for that package. When `ChannelPriority.Disabled`
68
+ it will search for every package in every channel.
69
+ timeout: The maximum time the solver is allowed to run.
70
+ exclude_newer: Exclude any record that is newer than the given datetime.
71
+ strategy: The strategy to use when multiple versions of a package are available.
72
+
73
+ * `"highest"`: Select the highest compatible version of all packages.
74
+ * `"lowest"`: Select the lowest compatible version of all packages.
75
+ * `"lowest-direct"`: Select the lowest compatible version for all
76
+ direct dependencies but the highest compatible version of transitive
77
+ dependencies.
78
+ constraints: Additional constraints that should be satisfied by the solver.
79
+ Packages included in the `constraints` are not necessarily installed,
80
+ but they must be satisfied by the solution.
81
+
82
+ Returns:
83
+ Resolved list of `RepoDataRecord`s.
84
+ """
85
+
86
+ platforms = platforms if platforms is not None else [Platform.current(), Platform("noarch")]
87
+
88
+ return [
89
+ RepoDataRecord._from_py_record(solved_package)
90
+ for solved_package in await py_solve(
91
+ sources=_convert_sources(sources),
92
+ platforms=[
93
+ platform._inner if isinstance(platform, Platform) else Platform(platform)._inner
94
+ for platform in platforms
95
+ ],
96
+ specs=[
97
+ spec._match_spec if isinstance(spec, MatchSpec) else PyMatchSpec(str(spec), True, True)
98
+ for spec in specs
99
+ ],
100
+ gateway=gateway._gateway,
101
+ locked_packages=[package._record for package in locked_packages or []],
102
+ pinned_packages=[package._record for package in pinned_packages or []],
103
+ virtual_packages=[
104
+ v_package.into_generic()._generic_virtual_package
105
+ if isinstance(v_package, VirtualPackage)
106
+ else v_package._generic_virtual_package
107
+ for v_package in virtual_packages or []
108
+ ],
109
+ channel_priority=channel_priority.value,
110
+ timeout=int(timeout / datetime.timedelta(microseconds=1)) if timeout else None,
111
+ exclude_newer_timestamp_ms=int(exclude_newer.replace(tzinfo=datetime.timezone.utc).timestamp() * 1000)
112
+ if exclude_newer
113
+ else None,
114
+ strategy=strategy,
115
+ constraints=[
116
+ constraint._match_spec
117
+ if isinstance(constraint, MatchSpec)
118
+ else PyMatchSpec(str(constraint), True, True)
119
+ for constraint in constraints
120
+ ]
121
+ if constraints is not None
122
+ else [],
123
+ )
124
+ ]
125
+
126
+
127
+ async def solve_with_sparse_repodata(
128
+ specs: Sequence[MatchSpec | str],
129
+ sparse_repodata: Sequence[SparseRepoData],
130
+ locked_packages: Optional[Sequence[RepoDataRecord]] = None,
131
+ pinned_packages: Optional[Sequence[RepoDataRecord]] = None,
132
+ virtual_packages: Optional[Sequence[GenericVirtualPackage | VirtualPackage]] = None,
133
+ timeout: Optional[datetime.timedelta] = None,
134
+ channel_priority: ChannelPriority = ChannelPriority.Strict,
135
+ exclude_newer: Optional[datetime.datetime] = None,
136
+ strategy: SolveStrategy = "highest",
137
+ constraints: Optional[Sequence[MatchSpec | str]] = None,
138
+ package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA,
139
+ ) -> List[RepoDataRecord]:
140
+ """
141
+ Resolve the dependencies and return the `RepoDataRecord`s
142
+ that should be present in the environment.
143
+
144
+ This function is similar to `solve` but instead of querying for repodata
145
+ with a `Gateway` object this function allows you to manually pass in the
146
+ repodata.
147
+
148
+ Arguments:
149
+ specs: A list of matchspec to solve.
150
+ sparse_repodata: The repodata to query for the packages.
151
+ locked_packages: Records of packages that are previously selected.
152
+ If the solver encounters multiple variants of a single
153
+ package (identified by its name), it will sort the records
154
+ and select the best possible version. However, if there
155
+ exists a locked version it will prefer that variant instead.
156
+ This is useful to reduce the number of packages that are
157
+ updated when installing new packages. Usually you add the
158
+ currently installed packages or packages from a lock-file here.
159
+ pinned_packages: Records of packages that are previously selected and CANNOT
160
+ be changed. If the solver encounters multiple variants of
161
+ a single package (identified by its name), it will sort the
162
+ records and select the best possible version. However, if
163
+ there is a variant available in the `pinned_packages` field it
164
+ will always select that version no matter what even if that
165
+ means other packages have to be downgraded.
166
+ virtual_packages: A list of virtual packages considered active.
167
+ channel_priority: (Default = ChannelPriority.Strict) When `ChannelPriority.Strict`
168
+ the channel that the package is first found in will be used as
169
+ the only channel for that package. When `ChannelPriority.Disabled`
170
+ it will search for every package in every channel.
171
+ timeout: The maximum time the solver is allowed to run.
172
+ exclude_newer: Exclude any record that is newer than the given datetime.
173
+ strategy: The strategy to use when multiple versions of a package are available.
174
+
175
+ * `"highest"`: Select the highest compatible version of all packages.
176
+ * `"lowest"`: Select the lowest compatible version of all packages.
177
+ * `"lowest-direct"`: Select the lowest compatible version for all
178
+ direct dependencies but the highest compatible version of transitive
179
+ dependencies.
180
+ constraints: Additional constraints that should be satisfied by the solver.
181
+ Packages included in the `constraints` are not necessarily installed,
182
+ but they must be satisfied by the solution.
183
+ package_format_selection: Defines which package formats are selected
184
+
185
+ Returns:
186
+ Resolved list of `RepoDataRecord`s.
187
+ """
188
+ return [
189
+ RepoDataRecord._from_py_record(solved_package)
190
+ for solved_package in await py_solve_with_sparse_repodata(
191
+ specs=[
192
+ spec._match_spec if isinstance(spec, MatchSpec) else PyMatchSpec(str(spec), True, True)
193
+ for spec in specs
194
+ ],
195
+ sparse_repodata=[package._sparse for package in sparse_repodata],
196
+ locked_packages=[package._record for package in locked_packages or []],
197
+ pinned_packages=[package._record for package in pinned_packages or []],
198
+ virtual_packages=[
199
+ v_package.into_generic()._generic_virtual_package
200
+ if isinstance(v_package, VirtualPackage)
201
+ else v_package._generic_virtual_package
202
+ for v_package in virtual_packages or []
203
+ ],
204
+ channel_priority=channel_priority.value,
205
+ timeout=int(timeout / datetime.timedelta(microseconds=1)) if timeout else None,
206
+ package_format_selection=package_format_selection.value,
207
+ exclude_newer_timestamp_ms=int(exclude_newer.replace(tzinfo=datetime.timezone.utc).timestamp() * 1000)
208
+ if exclude_newer
209
+ else None,
210
+ strategy=strategy,
211
+ constraints=[
212
+ constraint._match_spec
213
+ if isinstance(constraint, MatchSpec)
214
+ else PyMatchSpec(str(constraint), True, True)
215
+ for constraint in constraints
216
+ ]
217
+ if constraints is not None
218
+ else [],
219
+ )
220
+ ]
@@ -0,0 +1,19 @@
1
+ try:
2
+ from rattler.rattler import get_rattler_version as _get_rattler_version
3
+
4
+ rattler_version_string = _get_rattler_version()
5
+ except ImportError:
6
+ # this is only useful for documentation
7
+ import warnings
8
+
9
+ warnings.warn("rattler binary missing!", stacklevel=2)
10
+ rattler_version_string = ""
11
+
12
+
13
+ def get_rattler_version() -> str:
14
+ """
15
+ Return the version of the Python Rattler package as a string.
16
+
17
+ If the Rattler binary is missing, returns an empty string.
18
+ """
19
+ return rattler_version_string
@@ -0,0 +1,5 @@
1
+ from rattler.version.version import Version
2
+ from rattler.version.version_spec import VersionSpec
3
+ from rattler.version.with_source import VersionWithSource
4
+
5
+ __all__ = ["Version", "VersionSpec", "VersionWithSource"]