py-rattler 0.7.2__cp38-abi3-win32.whl → 0.8.2__cp38-abi3-win32.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.

Potentially problematic release.


This version of py-rattler might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: py-rattler
3
- Version: 0.7.2
3
+ Version: 0.8.2
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -1,14 +1,16 @@
1
- py_rattler-0.7.2.dist-info/METADATA,sha256=jM4R-xzJe2xXBkhFseRE1QGP2XfH6Sf_JVmqDi0lMrI,8036
2
- py_rattler-0.7.2.dist-info/WHEEL,sha256=fEuvyTnWBaFFqUK_-nJdc8PSyUVWaUnyNgRH_ePN1nU,90
3
- py_rattler-0.7.2.dist-info/license_files/LICENSE,sha256=dwHz2yahpPvgij5rWUfP4xwZgfEVFePgY1j2DQyY0C0,1530
1
+ py_rattler-0.8.2.dist-info/METADATA,sha256=JyKGEl1vktN4a3ySTywiB_RfAeZ1VpF0_rLynEPeiUg,8036
2
+ py_rattler-0.8.2.dist-info/WHEEL,sha256=fEuvyTnWBaFFqUK_-nJdc8PSyUVWaUnyNgRH_ePN1nU,90
3
+ py_rattler-0.8.2.dist-info/license_files/LICENSE,sha256=dwHz2yahpPvgij5rWUfP4xwZgfEVFePgY1j2DQyY0C0,1530
4
4
  rattler/channel/channel.py,sha256=X0rUb2VtxIzHzWaG8nsoH8l8q9htalzxSrv77moBIuw,2568
5
5
  rattler/channel/channel_config.py,sha256=fubqr_KtR6FzpGP-5W-v8anEjuH7kGt8hPHQ_ojmKZ8,1575
6
6
  rattler/channel/channel_priority.py,sha256=zPb2CG7RUBJVH2f-pbaxnYIDIUEvGjDJLS5-L8-CgUM,488
7
7
  rattler/channel/__init__.py,sha256=66ZzlAEanXVHmRFZ5W3SSz4XaaPbOD_drHYNGtMvA7w,226
8
- rattler/exceptions.py,sha256=D11mP_ImCHa7yilb5pCkdWrsVW2hWJoWDWT3Se-dB08,3952
8
+ rattler/exceptions.py,sha256=LI7yj9TPgORKcIvl6KAhp3MqTXvvGzMI450K9jh0imc,4174
9
+ rattler/explicit_environment/environment.py,sha256=EoKZcC5t7iBTtHFtq5wkjN65ZMnRjCl0cJsCpJs4JYw,2710
10
+ rattler/explicit_environment/__init__.py,sha256=hslNA2pDXqP5fgbnVYJAqr8j0vucFi48_vnqb3r2hfo,173
9
11
  rattler/index/index.py,sha256=h-QGux6h7YLXmZkP-sBOfQD0eUXubWUPmOOpVVzZccU,1161
10
12
  rattler/index/__init__.py,sha256=6ZfzMgGlZREtm-hBBOAh-Y4t52SMe4daJDFGzhBsjww,62
11
- rattler/install/installer.py,sha256=sxbQsPbth-t4PXU8vYOOayHl4PxWYnLZW9_Mfs8dQ38,3504
13
+ rattler/install/installer.py,sha256=Uc711Z6TvbrHHLo7YEdITZ9txkam5yWdvIxstuDS_HM,3464
12
14
  rattler/install/__init__.py,sha256=qV-pHnLSxQ57o3rVFuedEaZD2_wKmtrO3l52u96Le74,72
13
15
  rattler/lock/channel.py,sha256=fWashbJ1-6WKQnlARggjp6T-QRmBcxhG-vyYEjUOla0,1383
14
16
  rattler/lock/environment.py,sha256=rcpHI9zKZNLcm_Oa4Jx4-VvaVaE9yBpqIE2vlZQMNwU,7904
@@ -20,27 +22,28 @@ rattler/lock/__init__.py,sha256=O1P94c1tbsG_P0HEZk2mCZOHbHmp5nRU4GmPq1_hCxE,487
20
22
  rattler/match_spec/match_spec.py,sha256=aWrZ6Fv3k2rXZymYK62Htivk-MB7FmEvyLeShAYV8W8,8483
21
23
  rattler/match_spec/nameless_match_spec.py,sha256=ZuayVPh8S4aezgTPd9eJ1i1hbzTmfJG90Z3HkvztprM,4782
22
24
  rattler/match_spec/__init__.py,sha256=dp2VL-6Cg-sJ1cBdiZ6RoZKOroR2z2lzX4SI0iAwGow,171
23
- rattler/networking/authenticated_client.py,sha256=PDQwmCiFZJF7VnM85aSgKfl0UPSlJeH-UcAt9YnEYy0,950
24
- rattler/networking/fetch_repo_data.py,sha256=CxbutHYt9wBlhb48tLjXp-0CIkB9spnQfYS2Z7sd6hQ,1436
25
- rattler/networking/__init__.py,sha256=1ycQwvODUOxyc8JqpzTd_72UXLrzuz6k0vw-CoT2OeQ,193
25
+ rattler/networking/client.py,sha256=7RXVJTbkvrYzI1UlJ092k8ly3-2iybPQjTmEjqL7dTg,1416
26
+ rattler/networking/fetch_repo_data.py,sha256=c5tc2-Z-fDUmyGWtfXYEdjSA0CZUBTX1hdxvFoKA-_M,1600
27
+ rattler/networking/middleware.py,sha256=72LnPxKckVtD7emAfr1axWcWo2VlTuWrJa8BSyD4QrI,1893
28
+ rattler/networking/__init__.py,sha256=rZaCy8e3XsOhspvES2tDksHZh08kQKwRuqmy1Iej0Ng,287
26
29
  rattler/package/about_json.py,sha256=6krfv7obbGfWByBx74R7xRQT6H6-W8Ygl_m0fI-TL7U,7310
27
30
  rattler/package/index_json.py,sha256=lD_jb-ACkB9bWriceZWtcHpbXddLjRlV8xcEggVR4vM,9878
28
- rattler/package/no_arch_type.py,sha256=MtqD0vlbX1WIMlR_CzDjbF3d7CewIjAtJMfqy9S6naE,3812
29
- rattler/package/package_name.py,sha256=BMHN870L4ghtKojSdsTDjlOUvTN-y_bKKEA8VUB-P0o,4260
30
- rattler/package/paths_json.py,sha256=5HSYdNCu9q_RJgC0AVz_Htx7bA5OpHFk_K05AHPARf8,15440
31
+ rattler/package/no_arch_type.py,sha256=oNx7KwfkxSoIQ5t_TcjiTZvcgs7fQLlUVRx4SCqJk-0,3826
32
+ rattler/package/package_name.py,sha256=CDMG8KEFMSV0IsVZm-Uujf_RPLV5FRK3K72T6e3no4w,4585
33
+ rattler/package/paths_json.py,sha256=GWbhT_C-DnKAsYKIWw9L1vHIUJBAX2dvc5MYQjiQAD0,15567
31
34
  rattler/package/run_exports_json.py,sha256=p1Y8M2z82fiUySYphoRcGUjn6vh83fib_G5eJxFs8Z0,6332
32
35
  rattler/package/__init__.py,sha256=zaSLXHJgBjoI1VOsuVeUgYGdGn5xnW9pb_o7T-s-rN0,541
33
36
  rattler/platform/arch.py,sha256=l2kg4E1Z2x-nrYtiF4vERvIVcqjLqwMfUcx-VQoLfmU,1203
34
- rattler/platform/platform.py,sha256=gJpY_43bGMA0Hg9k6nVZrR7JN5f54ajXyJjCM7ffIwI,4169
37
+ rattler/platform/platform.py,sha256=HmdY9Ssg7CrEq1kYhE1JMnHCNZ5xmQZN9W_kocw0kfo,4514
35
38
  rattler/platform/__init__.py,sha256=QKFVTYNuY8aZrUbi0kOjP0Iw0lbBH0BeUFtLUitUkGg,158
36
- rattler/prefix/prefix_paths.py,sha256=0sowl4iTi10eKcQOxUGykOwnBPAKdqkK_MDGey856UE,8845
37
- rattler/prefix/prefix_record.py,sha256=SYfCsqXT-mwvqFXMjdLAYXHWjfoFtCyx17Y99z738-Q,4667
39
+ rattler/prefix/prefix_paths.py,sha256=JaK0j_2peGc566plCBLE7YjfbUJ5PAy25kfxoQOwO7E,13261
40
+ rattler/prefix/prefix_record.py,sha256=Jo_Cr5POavX09LYy0xr9d7kbSvFmxilFN0OYp58dUbc,6058
38
41
  rattler/prefix/__init__.py,sha256=Pr1a0qnpUz_0FZgi79BBszdtWr1x84E_bd0f9ux9s64,225
39
42
  rattler/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- rattler/repo_data/gateway.py,sha256=mrunz-HGVQvcanLTRfyFf9BIsEJoE0X6huGzJV4K9K4,8485
41
- rattler/repo_data/package_record.py,sha256=t59CkqlJR0gV0WMqjuyKYeIv566N6it_C88ar0au2vs,15474
43
+ rattler/repo_data/gateway.py,sha256=iWy389xbjExt4wiqoYcIyngV4ksmobQlzXz23O24tFU,9804
44
+ rattler/repo_data/package_record.py,sha256=B6SBu6S1hmpoZHPxUB0_iaSJaFIHAKWwlBm13EGrh0M,28754
42
45
  rattler/repo_data/patch_instructions.py,sha256=WlI9gXPEvbYQUkxZpr5hi1u3PypkaaXAjpu0Plp2kCA,716
43
- rattler/repo_data/record.py,sha256=0vHyXKuMQVY1KjskvKkTO-Mksn6E5PhiHT4gC0QlF28,2755
46
+ rattler/repo_data/record.py,sha256=OTZrr2FUeBGqVKwjiu-1n7uiY_GnwDVFk77gZy6ozxk,4736
44
47
  rattler/repo_data/repo_data.py,sha256=PhFiR_A2YvjlTb6pU3bV0kIWwSla2A8CJeXd5lzVRpk,2338
45
48
  rattler/repo_data/sparse.py,sha256=9suNN-5LIzkXnAfJJvyJv3FVCsREZOGdOXDkTS3-5CE,6333
46
49
  rattler/repo_data/__init__.py,sha256=JdbHMi6RO2GpKp0ZyH32x7xvIig9cJjXgAJxuBpGpng,511
@@ -55,6 +58,6 @@ rattler/version/__init__.py,sha256=mstm5fHMHif1fXw0jo0giftoVUGjFGX2GxvASD5kSCU,1
55
58
  rattler/virtual_package/generic.py,sha256=XOCqsULIrVbZzjf2_629HZWnplZifqo-fWkjtUTvJFE,4547
56
59
  rattler/virtual_package/virtual_package.py,sha256=Ajikn1F6VMlJKzKmKcnolHnfhsPRZBgt9iMwKQVXoaI,6853
57
60
  rattler/virtual_package/__init__.py,sha256=PjKMWmztuN2ZbEn9u6l79dPntiRhH3f2zLH2Fvq8hu0,266
58
- rattler/__init__.py,sha256=_ck7oPHkD2mClp1QVlL9liQG303RetrEVdhZXNXbR2Q,2305
59
- rattler/rattler.pyd,sha256=XwfrGKjNSyTY4M0JLjajcA65YhOseOGMncbOqEWLXwU,13255168
60
- py_rattler-0.7.2.dist-info/RECORD,,
61
+ rattler/__init__.py,sha256=rgdyfibWyIinwUiMH1SSlH65G-l5BynbS5amniKpMXc,2351
62
+ rattler/rattler.pyd,sha256=dFuhBSyuHxJ6SWqB7rr_kjY59eMUJ3_ix9qFt5Ct6q4,13666304
63
+ py_rattler-0.8.2.dist-info/RECORD,,
rattler/__init__.py CHANGED
@@ -10,7 +10,7 @@ from rattler.repo_data import (
10
10
  SourceConfig,
11
11
  )
12
12
  from rattler.channel import Channel, ChannelConfig, ChannelPriority
13
- from rattler.networking import AuthenticatedClient, fetch_repo_data
13
+ from rattler.networking import Client, fetch_repo_data
14
14
  from rattler.virtual_package import GenericVirtualPackage, VirtualPackage, VirtualPackageOverrides, Override
15
15
  from rattler.package import (
16
16
  PackageName,
@@ -23,6 +23,7 @@ from rattler.package import (
23
23
  FileMode,
24
24
  IndexJson,
25
25
  )
26
+ from rattler.package.no_arch_type import NoArchType
26
27
  from rattler.prefix import PrefixRecord, PrefixPaths, PrefixPathsEntry, PrefixPathType
27
28
  from rattler.platform import Platform
28
29
  from rattler.utils.rattler_version import get_rattler_version as _get_rattler_version
@@ -51,7 +52,7 @@ __all__ = [
51
52
  "Channel",
52
53
  "ChannelConfig",
53
54
  "ChannelPriority",
54
- "AuthenticatedClient",
55
+ "Client",
55
56
  "PatchInstructions",
56
57
  "RepoDataRecord",
57
58
  "RepoData",
@@ -88,4 +89,5 @@ __all__ = [
88
89
  "IndexJson",
89
90
  "Gateway",
90
91
  "SourceConfig",
92
+ "NoArchType",
91
93
  ]
rattler/exceptions.py CHANGED
@@ -20,6 +20,7 @@ try:
20
20
  EnvironmentCreationError,
21
21
  ExtractError,
22
22
  GatewayError,
23
+ ValidatePackageRecordsException,
23
24
  )
24
25
  except ImportError:
25
26
  # They are only redefined for documentation purposes
@@ -85,6 +86,9 @@ except ImportError:
85
86
  class GatewayError(Exception): # type: ignore[no-redef]
86
87
  """An error that can occur when querying the repodata gateway."""
87
88
 
89
+ class ValidatePackageRecordsException(Exception): # type: ignore[no-redef]
90
+ """An error when validating package records."""
91
+
88
92
 
89
93
  __all__ = [
90
94
  "ActivationError",
@@ -107,4 +111,5 @@ __all__ = [
107
111
  "EnvironmentCreationError",
108
112
  "ExtractError",
109
113
  "GatewayError",
114
+ "ValidatePackageRecordsException",
110
115
  ]
@@ -0,0 +1,3 @@
1
+ from rattler.explicit_environment.environment import ExplicitEnvironmentSpec, ExplicitEnvironmentEntry
2
+
3
+ __all__ = ["ExplicitEnvironmentSpec", "ExplicitEnvironmentEntry"]
@@ -0,0 +1,69 @@
1
+ from pathlib import Path
2
+ from typing import List, Optional
3
+
4
+ from rattler.rattler import PyExplicitEnvironmentSpec as _PyExplicitEnvironmentSpec
5
+ from rattler.rattler import PyExplicitEnvironmentEntry as _PyExplicitEnvironmentEntry
6
+ from rattler.platform import Platform
7
+
8
+
9
+ class ExplicitEnvironmentEntry:
10
+ """A wrapper around an explicit environment entry which represents a URL to a package"""
11
+
12
+ def __init__(self, inner: _PyExplicitEnvironmentEntry) -> None:
13
+ self._inner = inner
14
+
15
+ @property
16
+ def url(self) -> str:
17
+ """Returns the URL of the package"""
18
+ return self._inner.url()
19
+
20
+
21
+ class ExplicitEnvironmentSpec:
22
+ """The explicit environment (e.g. env.txt) file that contains a list of all URLs in a environment"""
23
+
24
+ def __init__(self, inner: _PyExplicitEnvironmentSpec) -> None:
25
+ self._inner = inner
26
+
27
+ @classmethod
28
+ def from_path(cls, path: Path) -> "ExplicitEnvironmentSpec":
29
+ """Parses the object from a file specified by a `path`, using a format appropriate for the file type.
30
+
31
+ For example, if the file is in text format, this function reads the data from the file at
32
+ the specified path, parses the text and returns the resulting object. If the file is
33
+ not in a parsable format or if the file could not be read, this function raises an error.
34
+ """
35
+ return cls(_PyExplicitEnvironmentSpec.from_path(path))
36
+
37
+ @classmethod
38
+ def from_str(cls, content: str) -> "ExplicitEnvironmentSpec":
39
+ """
40
+ Parses the object from a string containing the explicit environment specification
41
+
42
+ Examples:
43
+
44
+ ```python
45
+ >>> spec = ExplicitEnvironmentSpec.from_str('''@EXPLICIT
46
+ ... # platform: linux-64
47
+ ... http://repo.anaconda.com/pkgs/main/linux-64/python-3.9.0-h3.tar.bz2
48
+ ... ''')
49
+ >>> spec.platform
50
+ Platform(linux-64)
51
+ >>> spec.packages[0].url
52
+ 'http://repo.anaconda.com/pkgs/main/linux-64/python-3.9.0-h3.tar.bz2'
53
+ >>>
54
+ ```
55
+ """
56
+ return cls(_PyExplicitEnvironmentSpec.from_str(content))
57
+
58
+ @property
59
+ def platform(self) -> Optional[Platform]:
60
+ """Returns the platform specified in the explicit environment specification"""
61
+ platform = self._inner.platform()
62
+ if platform is not None:
63
+ return Platform._from_py_platform(platform)
64
+ return None
65
+
66
+ @property
67
+ def packages(self) -> List[ExplicitEnvironmentEntry]:
68
+ """Returns the environment entries (URLs) specified in the explicit environment specification"""
69
+ return [ExplicitEnvironmentEntry(p) for p in self._inner.packages()]
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
  import os
3
3
  from typing import List, Optional
4
4
 
5
- from rattler.networking.authenticated_client import AuthenticatedClient
5
+ from rattler.networking.client import Client
6
6
  from rattler.platform.platform import Platform
7
7
  from rattler.prefix.prefix_record import PrefixRecord
8
8
  from rattler.repo_data.record import RepoDataRecord
@@ -18,7 +18,7 @@ async def install(
18
18
  platform: Optional[Platform] = None,
19
19
  execute_link_scripts: bool = False,
20
20
  show_progress: bool = True,
21
- client: Optional[AuthenticatedClient] = None,
21
+ client: Optional[Client] = None,
22
22
  ) -> None:
23
23
  """
24
24
  Create an environment by downloading and linking the `dependencies` in
@@ -1,4 +1,5 @@
1
- from rattler.networking.authenticated_client import AuthenticatedClient
1
+ from rattler.networking.client import Client
2
+ from rattler.networking.middleware import MirrorMiddleware, AuthenticationMiddleware
2
3
  from rattler.networking.fetch_repo_data import fetch_repo_data
3
4
 
4
- __all__ = ["AuthenticatedClient", "fetch_repo_data"]
5
+ __all__ = ["fetch_repo_data", "Client", "MirrorMiddleware", "AuthenticationMiddleware"]
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+ from rattler.rattler import PyClientWithMiddleware
3
+ from rattler.networking.middleware import AuthenticationMiddleware, MirrorMiddleware
4
+
5
+
6
+ class Client:
7
+ """
8
+ A client that can be used to make requests.
9
+ """
10
+
11
+ def __init__(self, middlewares: list[AuthenticationMiddleware | MirrorMiddleware] | None = None) -> None:
12
+ self._client = PyClientWithMiddleware(
13
+ [middleware._middleware for middleware in middlewares] if middlewares else None
14
+ )
15
+
16
+ @classmethod
17
+ def _from_ffi_object(cls, client: PyClientWithMiddleware) -> Client:
18
+ """
19
+ Construct py-rattler Client from PyClientWithMiddleware FFI object.
20
+ """
21
+ client = cls.__new__(cls)
22
+ client._client = client
23
+ return client
24
+
25
+ def __repr__(self) -> str:
26
+ """
27
+ Returns a representation of the Client
28
+
29
+ Examples
30
+ --------
31
+ ```python
32
+ >>> Client()
33
+ Client()
34
+ >>>
35
+ ```
36
+ """
37
+ return f"{type(self).__name__}()"
38
+
39
+ @staticmethod
40
+ def authenticated_client() -> Client:
41
+ """
42
+ Returns an authenticated client.
43
+
44
+ Examples
45
+ --------
46
+ ```python
47
+ >>> Client.authenticated_client()
48
+ Client()
49
+ >>>
50
+ ```
51
+ """
52
+ return Client([AuthenticationMiddleware()])
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
  from typing import Callable, List, Optional, Union, TYPE_CHECKING
3
3
 
4
4
 
5
+ from rattler.networking.client import Client
5
6
  from rattler.rattler import py_fetch_repo_data
6
7
  from rattler.repo_data.sparse import SparseRepoData
7
8
 
@@ -17,6 +18,7 @@ async def fetch_repo_data(
17
18
  platforms: List[Platform],
18
19
  cache_path: Union[str, os.PathLike[str]],
19
20
  callback: Optional[Callable[[int, int], None]],
21
+ client: Optional[Client] = None,
20
22
  ) -> List[SparseRepoData]:
21
23
  """
22
24
  Returns a list of RepoData for given channels and platform.
@@ -29,6 +31,7 @@ async def fetch_repo_data(
29
31
  be downloaded.
30
32
  callback: A `Callable[[int, int], None]` to report the download
31
33
  progress of repo data.
34
+ client: A `Client` to use for fetching the repo data.
32
35
 
33
36
  Returns:
34
37
  A list of `SparseRepoData` for requested channels and platforms.
@@ -38,6 +41,7 @@ async def fetch_repo_data(
38
41
  [platform._inner for platform in platforms],
39
42
  cache_path,
40
43
  callback,
44
+ client,
41
45
  )
42
46
 
43
47
  return [SparseRepoData._from_py_sparse_repo_data(repo_data) for repo_data in repo_data_list]
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+ from rattler.rattler import PyMirrorMiddleware, PyAuthenticationMiddleware
3
+
4
+
5
+ class MirrorMiddleware:
6
+ def __init__(self, mirrors: dict[str, list[str]]) -> None:
7
+ """
8
+ Create a new MirrorMiddleware instance.
9
+ The mirrors argument should be a dictionary where the keys are the
10
+ original mirror URLs and the values are lists of mirror URLs to
11
+ replace the original mirror with.
12
+
13
+ Examples
14
+ --------
15
+ ```python
16
+ >>> from rattler.networking import Client
17
+ >>> middleware = MirrorMiddleware({"https://conda.anaconda.org/conda-forge": ["https://repo.prefix.dev/conda-forge"]})
18
+ >>> middleware
19
+ MirrorMiddleware()
20
+ >>> Client([middleware])
21
+ Client()
22
+ >>>
23
+ ```
24
+ """
25
+ self._middleware = PyMirrorMiddleware(mirrors)
26
+
27
+ def __repr__(self) -> str:
28
+ """
29
+ Returns a representation of the Middleware
30
+
31
+ Examples
32
+ --------
33
+ ```python
34
+ >>> middleware = MirrorMiddleware({"https://conda.anaconda.org/conda-forge": ["https://repo.prefix.dev/conda-forge"]})
35
+ >>> middleware
36
+ MirrorMiddleware()
37
+ >>>
38
+ ```
39
+ """
40
+ return f"{type(self).__name__}()"
41
+
42
+
43
+ class AuthenticationMiddleware:
44
+ def __init__(self) -> None:
45
+ self._middleware = PyAuthenticationMiddleware()
46
+
47
+ def __repr__(self) -> str:
48
+ """
49
+ Returns a representation of the Middleware
50
+
51
+ Examples
52
+ --------
53
+ ```python
54
+ >>> from rattler.networking import Client
55
+ >>> middleware = AuthenticationMiddleware()
56
+ >>> middleware
57
+ AuthenticationMiddleware()
58
+ >>> Client([middleware])
59
+ Client()
60
+ >>>
61
+ ```
62
+ """
63
+ return f"{type(self).__name__}()"
@@ -10,13 +10,10 @@ class NoArchType:
10
10
  def __init__(self, noarch: Optional[str] = None) -> None:
11
11
  if noarch is None:
12
12
  self._noarch = PyNoArchType.none()
13
- self._source = None
14
13
  elif noarch == "python":
15
14
  self._noarch = PyNoArchType.python()
16
- self._source = "python"
17
15
  elif noarch == "generic":
18
16
  self._noarch = PyNoArchType.generic()
19
- self._source = "generic"
20
17
  else:
21
18
  raise ValueError(
22
19
  "NoArchType constructor received unsupported value " f"{noarch} for the `noarch` parameter"
@@ -27,7 +24,6 @@ class NoArchType:
27
24
  """Construct Rattler NoArchType from FFI PyNoArchType object."""
28
25
  no_arch_type = cls.__new__(cls)
29
26
  no_arch_type._noarch = py_no_arch_type
30
- no_arch_type._source = py_no_arch_type
31
27
  return no_arch_type
32
28
 
33
29
  @property
@@ -137,4 +133,10 @@ class NoArchType:
137
133
  >>>
138
134
  ```
139
135
  """
140
- return f'NoArchType("{self._source}")'
136
+
137
+ if self._noarch.is_python:
138
+ return 'NoArchType("python")'
139
+ elif self._noarch.is_generic:
140
+ return 'NoArchType("generic")'
141
+ else:
142
+ return "NoArchType(None)"
@@ -101,10 +101,15 @@ class PackageName:
101
101
  >>> PackageName("test-abc") == PackageName("test-ABC")
102
102
  True
103
103
  >>> PackageName("test-abc") == "test-abc"
104
+ True
105
+ >>> PackageName("test-abc") == "not-test-abc"
104
106
  False
105
107
  >>>
106
108
  ```
107
109
  """
110
+ if isinstance(other, str):
111
+ return self._name == PyPackageName(other)
112
+
108
113
  if not isinstance(other, PackageName):
109
114
  return False
110
115
 
@@ -124,10 +129,15 @@ class PackageName:
124
129
  >>> PackageName("test-abc") != PackageName("abc-test")
125
130
  True
126
131
  >>> PackageName("test-abc") != "test-abc"
132
+ False
133
+ >>> PackageName("test-abc") != "not-test-abc"
127
134
  True
128
135
  >>>
129
136
  ```
130
137
  """
138
+ if isinstance(other, str):
139
+ return self._name != PyPackageName(other)
140
+
131
141
  if not isinstance(other, PackageName):
132
142
  return True
133
143
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import os
3
3
  from pathlib import Path
4
- from typing import List, Optional
4
+ from typing import List, Optional, Literal
5
5
  from rattler.rattler import (
6
6
  PyPathsJson,
7
7
  PyPathsEntry,
@@ -456,6 +456,9 @@ class FileMode:
456
456
 
457
457
  _inner: PyFileMode | None = None
458
458
 
459
+ def __init__(self, file_mode: Literal["binary", "text"]) -> None:
460
+ self._inner = PyFileMode(file_mode)
461
+
459
462
  @property
460
463
  def binary(self) -> bool:
461
464
  """
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import Any, Dict, Literal, Tuple
2
+ from typing import Any, Dict, Literal, Tuple, Optional
3
3
 
4
4
  from rattler.rattler import PyPlatform
5
5
  from rattler.platform.arch import Arch
@@ -174,3 +174,18 @@ class Platform(metaclass=PlatformSingleton):
174
174
  ```
175
175
  """
176
176
  return Arch._from_py_arch(self._inner.arch())
177
+
178
+ @property
179
+ def only_platform(self) -> Optional[str]:
180
+ """
181
+ Return the platform without the architecture.
182
+
183
+ Examples
184
+ --------
185
+ ```python
186
+ >>> Platform("linux-64").only_platform
187
+ 'linux'
188
+ >>>
189
+ ```
190
+ """
191
+ return self._inner.only_platform