py-rattler 0.11.0__cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl → 0.13.0__cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.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.4
2
2
  Name: py-rattler
3
- Version: 0.11.0
3
+ Version: 0.13.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -48,7 +48,7 @@ Project-URL: Issues, https://github.com/conda/rattler/labels/python-bindings
48
48
  [pixi-badge]:https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/prefix-dev/pixi/main/assets/badge/v0.json&style=flat-square
49
49
  [pixi-url]: https://pixi.sh
50
50
 
51
- Rattler is a library that provides common functionality used within the conda ecosystem ([what is conda & conda-forge?](#what-is-conda-conda-forge)).
51
+ Rattler is a library that provides common functionality used within the conda ecosystem ([what is conda & conda-forge?](#what-is-conda--conda-forge)).
52
52
  The goal of the library is to enable programs and other libraries to easily interact with the conda ecosystem without being dependent on Python.
53
53
  Its primary use case is as a library that you can use to provide conda related workflows in your own tools.
54
54
 
@@ -1,62 +1,62 @@
1
- py_rattler-0.11.0.dist-info/METADATA,sha256=Vc8gdxyPOALNF_tAnjDiNPGhuKL8Vw5wsDzbtIfP8m8,7909
2
- py_rattler-0.11.0.dist-info/WHEEL,sha256=3TinPYnt4CFOqWAu30MbbZRMdVq42rDXuvLp9oRb4Ew,129
1
+ py_rattler-0.13.0.dist-info/METADATA,sha256=3xOCT83hJXxwLyufYzc5J3Vujj7idN3qQ-KxNzy1PH0,7910
2
+ py_rattler-0.13.0.dist-info/WHEEL,sha256=3TinPYnt4CFOqWAu30MbbZRMdVq42rDXuvLp9oRb4Ew,129
3
+ rattler/package_streaming/__init__.py,sha256=I-mbr0sJnHzdFQP8v0Yb_GKpu4bIO3JbAJtq_wzA71Q,898
3
4
  rattler/solver/__init__.py,sha256=NZabrelb_pcqOi5PyZTr3OeBbjd85IqW1-2ymOBO-k0,119
4
- rattler/solver/solver.py,sha256=5T6izd_cOhwIAwlreJIUgqXpyTOCxOgW0Ll786Q6NqM,10922
5
- rattler/explicit_environment/environment.py,sha256=Dqcvm5c7C3K0FJ04YVN8WIUrl0R8Fe2TeXZ4Qq8Dg-0,2641
5
+ rattler/solver/solver.py,sha256=EEF86vA-ryVuBmq5uOomgzPq1BGXsNcAhJvf7JKVVDQ,11259
6
6
  rattler/explicit_environment/__init__.py,sha256=QHmwZkdVt-tFL-tEEdhLdH3apuI5F7ElpMzCRZeH3_o,170
7
- rattler/package/no_arch_type.py,sha256=NnH4s1j9E0JrZTEeDayGssVpcpbY2i-66_0N9UJa328,3684
8
- rattler/package/run_exports_json.py,sha256=DNGoylVj5huRG8g0a1KtG1OQYJdSrkRb8ZMZZa8HGCk,9304
9
- rattler/package/paths_json.py,sha256=DzEKrKdZa17f1jiAuO59Bt9Ny4dS2i11tsCfnQvr3Ho,21448
10
- rattler/package/about_json.py,sha256=D61slvy2aYxlU2BF30DMc6nNhB0Wy54tpxp-l9QDVqY,8952
11
- rattler/package/__init__.py,sha256=2miuQoS1eNvgxQQvDJcU5h4W5tjRtBuu1u2yU5rnWcg,518
12
- rattler/package/index_json.py,sha256=D4HvKPN7cFHTmANFbzuueGFMQIwQrjIfcUAlgkL7FbE,12418
13
- rattler/package/package_name.py,sha256=bX5CpTwyWOOuUlrejHmbJzz1R0KcchtWHLskOfA-Dlk,4426
14
- rattler/prefix/prefix_paths.py,sha256=Ausp9xbZTUbsbjZJxCpTUuitcUhnr1DAgawHAyiVFh0,12819
15
- rattler/prefix/prefix_record.py,sha256=gaNcBp-enw_uMuZmZDC8nlEzk4dR6s8v0LsF7w6wVto,5866
16
- rattler/prefix/__init__.py,sha256=fm0eLuHmqO4pX8T2G9GKeZanknh2B5NeppySqLEg_7Q,221
17
- rattler/exceptions.py,sha256=2ivs3zwllwQwn1InBiArbrZbTzPXpssv7fzZkGdRpnI,4059
18
- rattler/package_streaming/__init__.py,sha256=I-mbr0sJnHzdFQP8v0Yb_GKpu4bIO3JbAJtq_wzA71Q,898
19
- rattler/install/installer.py,sha256=akUuojDLiP5jcd1vbX__xLjBg2B46sFNSKk4RBYjvIc,3559
20
- rattler/install/__init__.py,sha256=F_DwKOql1YkdV78JV5jT0RglNhs2ZwSup9uWGv9wO4I,69
21
- rattler/shell/shell.py,sha256=n9bAb0YQpdiOB62nFUIuWDoAzXnKRi1Y-fHEW9wVIg4,4442
22
- rattler/shell/__init__.py,sha256=GW5Amfmw7ln9l4kBBZCelaJxYBP5xbk5NjdNLMZhNMU,179
23
- rattler/match_spec/nameless_match_spec.py,sha256=f4P44Im6CL_yq7rcSE2XRfHRRSLZ1aAKVgrNggpzQ6c,4618
7
+ rattler/explicit_environment/environment.py,sha256=Dqcvm5c7C3K0FJ04YVN8WIUrl0R8Fe2TeXZ4Qq8Dg-0,2641
24
8
  rattler/match_spec/__init__.py,sha256=uBV3ov1VlCIZlIWhkxxMPcTqRBF5p5lqvT2g6kQv5kQ,167
25
- rattler/match_spec/match_spec.py,sha256=fOxCH0mPLppOJ_weRB40R6Ft9ou4QwXuKPYIjlbezA8,8243
26
- rattler/networking/middleware.py,sha256=S1eArDWo45dKo8Um6mMYMOPs_OIdhLamejEQs8KorCQ,4838
27
- rattler/networking/client.py,sha256=rRmbeEQYO1afHDgjgSncq68hSkFpyZ1ktYgC_Q_7LBQ,1528
28
- rattler/networking/fetch_repo_data.py,sha256=sO3dDNdvJev6TOblnGEzpFYnY2xorfr5A5zrjsTDbWk,3714
29
- rattler/networking/__init__.py,sha256=Wlob5pywEgiqmAq8sVKyJS6qOpRegKemtcXTkwDED20,474
30
- rattler/virtual_package/generic.py,sha256=ztDVHLNbO2SemZSpdoa2SdoXcZT1hopvBFQ11fNBZmQ,4411
31
- rattler/virtual_package/virtual_package.py,sha256=nmqL2D2KV9rZzczurAvE5WgYqlBYWsbOzVRdYuMvqnM,6654
32
- rattler/virtual_package/__init__.py,sha256=pOvvD-8V6Ld5gYBj2KPI3-cZLx8m2hcl6dqRUoBTHuw,262
33
- rattler/platform/arch.py,sha256=7tanyDql5BvDvY9UryEXyTJ9nWRfx6bn7BWrl6fGEfI,1145
34
- rattler/platform/__init__.py,sha256=YZaXxnJmG_WjYbhIAxA0jQDhaPYAR4rTVQCm4yRoyZQ,154
35
- rattler/platform/platform.py,sha256=h6XVfjf5VtTmb35sjNB_1k0vretaHteJaCyOxmZWaHU,4323
36
- rattler/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- rattler/utils/rattler_version.py,sha256=eXAVN6NYg5EmsQ_DrfgxW1yJ_eWAlWx7IANasMRYgV4,526
38
- rattler/channel/channel_priority.py,sha256=OQfCHp_DeInkMB0YahCf2X7yCk0_RtM_C_Vy4Ny-65M,474
39
- rattler/channel/channel.py,sha256=kGeZKa_YkSM943CA1i_8O1FXG9kS9hkrnmSl6OhkbbQ,2474
40
- rattler/channel/__init__.py,sha256=K-ZAo0qFzchXWP-6DpMHLg_djGD25-0CRwusisIGp8k,221
41
- rattler/channel/channel_config.py,sha256=rRD4dGeHTBIcm3vTuQR1wTGTELNdN69yq4lyCaTaN3M,1532
9
+ rattler/match_spec/match_spec.py,sha256=fyrvd9VUURJyHaJDqNdzJNa3dZZpKLUmhjGVWtdGV4w,9525
10
+ rattler/match_spec/nameless_match_spec.py,sha256=f4P44Im6CL_yq7rcSE2XRfHRRSLZ1aAKVgrNggpzQ6c,4618
11
+ rattler/lock/lock_file.py,sha256=ZP-ElSJ7WKkqOE6rj4U6OmM63GLcDH_yTg1H_Qoa60E,3455
12
+ rattler/lock/__init__.py,sha256=JkighOKfDQBqX3xrw1NXYlA_j1IFNI47_s6p2XvFtQc,571
42
13
  rattler/lock/package.py,sha256=C-lvnRWoRtj9CBRR2i5Eku_lFnBDI9Bf8vY57DWZ4YU,9035
43
14
  rattler/lock/hash.py,sha256=qNig1sf5EfRfaCK9x352DgqTpLdo75Gu4qvRZDbL33Q,805
44
- rattler/lock/lock_file.py,sha256=ZP-ElSJ7WKkqOE6rj4U6OmM63GLcDH_yTg1H_Qoa60E,3455
45
15
  rattler/lock/environment.py,sha256=sbcGqkb9rrGwpVCucDKkwdp2SFOyHZQGqvBArGEZFYs,7915
46
16
  rattler/lock/channel.py,sha256=PaLb-vWRLTJWUx7fyMdP2Tow5wMlGuq3WUrHkrQIzeg,1331
47
- rattler/lock/__init__.py,sha256=JkighOKfDQBqX3xrw1NXYlA_j1IFNI47_s6p2XvFtQc,571
48
- rattler/__init__.py,sha256=hbm0F5-1Q15xXfj8Ln1OaIq30BFGiryiD9GmU8XYrEc,2370
49
- rattler/index/__init__.py,sha256=Y-fiAzMcJSbL006dpALwGEhuMSTxuR1XC4o2gMqWcKA,87
50
- rattler/index/index.py,sha256=gpFHGuoQ-y4rY1i0vd_hDOiTYz5KtuInL-fFQvXj6bM,3795
51
- rattler/version/version.py,sha256=06are6AdWAEDQafi5RrB8ORH87CcmtjcmpOaMhEwdn0,15973
52
- rattler/version/with_source.py,sha256=nEW_jetdsB-5hKnxHVYgwOsd0EAe0fNKaCLlD4fIZiM,2539
53
- rattler/version/__init__.py,sha256=FQ_4xuCz_2tTPlIeSA_1SkPEP_DpuXw6tDDjsptMTZo,146
54
- rattler/repo_data/sparse.py,sha256=-XGT7vCAjKGdT0Ai7eF6Iff0N2dQRCYGAbxnFtGabko,6162
55
- rattler/repo_data/gateway.py,sha256=KOuSP8UwQDhOf-fL11iDRM8Kmol9-Dt5KWKV0UXB_oI,10111
56
- rattler/repo_data/package_record.py,sha256=CwOaRzhG25PQnw5wJ8m6GAZ6O-B87s3HE_SE_wPJxFs,27837
57
- rattler/repo_data/__init__.py,sha256=I7sC1bFPuXAUlb9gout2bGd1jYOPsHrsoDpSGniwpCk,495
17
+ rattler/prefix/prefix_record.py,sha256=KWbjcBJO-KpdWz2VEYdlz_RPLpLByyaec0aViILi_EM,6290
18
+ rattler/prefix/__init__.py,sha256=gkgyqZ0yTmxOCW8DHuSG-X0spEzb8BIoiox8YG50XYc,257
19
+ rattler/prefix/prefix_paths.py,sha256=B0EwOFkVbSzuLChdjkjenTehfxjXwwMBIodSGOfBHFU,12828
20
+ rattler/platform/arch.py,sha256=7tanyDql5BvDvY9UryEXyTJ9nWRfx6bn7BWrl6fGEfI,1145
21
+ rattler/platform/__init__.py,sha256=YZaXxnJmG_WjYbhIAxA0jQDhaPYAR4rTVQCm4yRoyZQ,154
22
+ rattler/platform/platform.py,sha256=H_P35Z0irNiyQX2fxX7ombMkGwyYa-Ow_iDIDxJrmG8,4395
23
+ rattler/__init__.py,sha256=QKjBUll9mX4TVwJy-dy5Gt8IezLnJz8EPTlKhOsw2IA,2476
24
+ rattler/repo_data/gateway.py,sha256=G9CTfz6Qc84Wo3QJSxWjsCH79WOohSxxUxYwKiss8ng,10141
25
+ rattler/repo_data/sparse.py,sha256=qO3XuIfvcDEfo8mHu8UB9JBoz0IR3k_kNR32ZTpbPWU,12542
26
+ rattler/repo_data/package_record.py,sha256=t8vxRsfAToIolhBRjt9lB4e5Q7Tm-FjZHUI9vhxd-eA,28358
27
+ rattler/repo_data/__init__.py,sha256=cMoMtFOJBGonfWxizGphWpXdQ1GYXDXos7ESYigfco8,549
58
28
  rattler/repo_data/repo_data.py,sha256=lB7hQ1SN5b2VxuOaOH1BOFeIXbRUf2fslitLyT5aVwo,2264
59
29
  rattler/repo_data/patch_instructions.py,sha256=TNa7NgLtqGQ6lSpibLFxuPFwsmqRLrORpDZOpeZ5fnk,694
60
30
  rattler/repo_data/record.py,sha256=6CK2-KyvVZ8kaZ2l-o4DFWivxMJE_ChkOrm97bmIjn4,4572
61
- rattler/rattler.abi3.so,sha256=RJuPfx1G2jKFDhCx7c1qR0PtpYZg5GOBE5-AVi0qdWg,50889720
62
- py_rattler-0.11.0.dist-info/RECORD,,
31
+ rattler/version/with_source.py,sha256=nEW_jetdsB-5hKnxHVYgwOsd0EAe0fNKaCLlD4fIZiM,2539
32
+ rattler/version/version.py,sha256=06are6AdWAEDQafi5RrB8ORH87CcmtjcmpOaMhEwdn0,15973
33
+ rattler/version/__init__.py,sha256=FQ_4xuCz_2tTPlIeSA_1SkPEP_DpuXw6tDDjsptMTZo,146
34
+ rattler/exceptions.py,sha256=2ivs3zwllwQwn1InBiArbrZbTzPXpssv7fzZkGdRpnI,4059
35
+ rattler/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ rattler/shell/__init__.py,sha256=GW5Amfmw7ln9l4kBBZCelaJxYBP5xbk5NjdNLMZhNMU,179
37
+ rattler/shell/shell.py,sha256=n9bAb0YQpdiOB62nFUIuWDoAzXnKRi1Y-fHEW9wVIg4,4442
38
+ rattler/package/paths_json.py,sha256=7l2Wmqobwcoe-TStXhoafWzXCT4OWif_yAAa6KVnKyg,21465
39
+ rattler/package/__init__.py,sha256=omXnLVICkiH7HiaUzpRWAaJxS955Uimm1pT8dejJgVU,624
40
+ rattler/package/about_json.py,sha256=FElWUXFNeF1gQJXE6lmYNEdxQjhsuimVObIeqxn3y8M,8958
41
+ rattler/package/run_exports_json.py,sha256=fZlM_H7IBuVi6lfL4SLsV_NDb22TgFhpCkxjm8YIvfg,9305
42
+ rattler/package/index_json.py,sha256=BxnJg5SPpiFsLhabz-Uuvc4ea_sg4N7Q-hqdQnXk8oc,12419
43
+ rattler/package/no_arch_type.py,sha256=y_1spiImY3654SDLRQWyp5mqr4l-gYKIuK4pCnEPj1s,3740
44
+ rattler/package/package_name.py,sha256=bX5CpTwyWOOuUlrejHmbJzz1R0KcchtWHLskOfA-Dlk,4426
45
+ rattler/install/__init__.py,sha256=F_DwKOql1YkdV78JV5jT0RglNhs2ZwSup9uWGv9wO4I,69
46
+ rattler/install/installer.py,sha256=akUuojDLiP5jcd1vbX__xLjBg2B46sFNSKk4RBYjvIc,3559
47
+ rattler/utils/rattler_version.py,sha256=eXAVN6NYg5EmsQ_DrfgxW1yJ_eWAlWx7IANasMRYgV4,526
48
+ rattler/networking/__init__.py,sha256=Wlob5pywEgiqmAq8sVKyJS6qOpRegKemtcXTkwDED20,474
49
+ rattler/networking/middleware.py,sha256=S1eArDWo45dKo8Um6mMYMOPs_OIdhLamejEQs8KorCQ,4838
50
+ rattler/networking/client.py,sha256=rRmbeEQYO1afHDgjgSncq68hSkFpyZ1ktYgC_Q_7LBQ,1528
51
+ rattler/networking/fetch_repo_data.py,sha256=sO3dDNdvJev6TOblnGEzpFYnY2xorfr5A5zrjsTDbWk,3714
52
+ rattler/index/__init__.py,sha256=Y-fiAzMcJSbL006dpALwGEhuMSTxuR1XC4o2gMqWcKA,87
53
+ rattler/index/index.py,sha256=jxm6v9gJtyg-AIizrpf0f5NOTMwA5SMvcbCL_HdnUG0,3725
54
+ rattler/virtual_package/__init__.py,sha256=pOvvD-8V6Ld5gYBj2KPI3-cZLx8m2hcl6dqRUoBTHuw,262
55
+ rattler/virtual_package/virtual_package.py,sha256=hrFvoT2LjIsW5ubfXdXEZnKlSIfLP5G4vrbJST9xukI,6707
56
+ rattler/virtual_package/generic.py,sha256=ztDVHLNbO2SemZSpdoa2SdoXcZT1hopvBFQ11fNBZmQ,4411
57
+ rattler/channel/__init__.py,sha256=K-ZAo0qFzchXWP-6DpMHLg_djGD25-0CRwusisIGp8k,221
58
+ rattler/channel/channel_config.py,sha256=rRD4dGeHTBIcm3vTuQR1wTGTELNdN69yq4lyCaTaN3M,1532
59
+ rattler/channel/channel_priority.py,sha256=OQfCHp_DeInkMB0YahCf2X7yCk0_RtM_C_Vy4Ny-65M,474
60
+ rattler/channel/channel.py,sha256=kGeZKa_YkSM943CA1i_8O1FXG9kS9hkrnmSl6OhkbbQ,2474
61
+ rattler/rattler.abi3.so,sha256=hLIA8TFIKaU895rMXqBo17_0VYahXU2n7I-C3NwYaaY,52561712
62
+ py_rattler-0.13.0.dist-info/RECORD,,
rattler/__init__.py CHANGED
@@ -8,6 +8,7 @@ from rattler.repo_data import (
8
8
  SparseRepoData,
9
9
  Gateway,
10
10
  SourceConfig,
11
+ PackageFormatSelection,
11
12
  )
12
13
  from rattler.channel import Channel, ChannelConfig, ChannelPriority
13
14
  from rattler.networking import Client, fetch_repo_data
@@ -22,9 +23,10 @@ from rattler.package import (
22
23
  PrefixPlaceholder,
23
24
  FileMode,
24
25
  IndexJson,
26
+ NoArchType,
27
+ NoArchLiteral,
25
28
  )
26
- from rattler.package.no_arch_type import NoArchType
27
- from rattler.prefix import PrefixRecord, PrefixPaths, PrefixPathsEntry, PrefixPathType
29
+ from rattler.prefix import PrefixRecord, PrefixPaths, PrefixPathsEntry, PrefixPathType, Link, LinkType
28
30
  from rattler.platform import Platform
29
31
  from rattler.utils.rattler_version import get_rattler_version as _get_rattler_version
30
32
  from rattler.install import install
@@ -69,6 +71,7 @@ __all__ = [
69
71
  "PrefixPathsEntry",
70
72
  "PrefixPathType",
71
73
  "SparseRepoData",
74
+ "PackageFormatSelection",
72
75
  "LockFile",
73
76
  "Environment",
74
77
  "LockChannel",
@@ -94,4 +97,7 @@ __all__ = [
94
97
  "Gateway",
95
98
  "SourceConfig",
96
99
  "NoArchType",
100
+ "NoArchLiteral",
101
+ "Link",
102
+ "LinkType",
97
103
  ]
rattler/index/index.py CHANGED
@@ -24,8 +24,8 @@ async def index_fs(
24
24
  Arguments:
25
25
  channel_directory: A `os.PathLike[str]` that is the directory containing subdirectories
26
26
  of dependencies to index.
27
- target_platform(optional): A `Platform` to index dependencies for.
28
- repodata_patch(optional): The name of the conda package (expected to be in the `noarch` subdir) that should be used for repodata patching.
27
+ target_platform: A `Platform` to index dependencies for.
28
+ repodata_patch: The name of the conda package (expected to be in the `noarch` subdir) that should be used for repodata patching.
29
29
  force: Whether to forcefully re-index all subdirs.
30
30
  max_parallel: The maximum number of packages to process in-memory simultaneously.
31
31
  """
@@ -64,11 +64,11 @@ async def index_s3(
64
64
  region: The region of the S3 bucket.
65
65
  endpoint_url: The endpoint URL of the S3 bucket.
66
66
  force_path_style: Whether to use path-style addressing for S3.
67
- access_key_id(optional): The access key ID to use for authentication.
68
- secret_access_key(optional): The secret access key to use for authentication.
69
- session_token(optional): The session token to use for authentication.
70
- target_platform(optional): A `Platform` to index dependencies for.
71
- repodata_patch(optional): The name of the conda package (expected to be in the `noarch` subdir) that should be used for repodata patching.
67
+ access_key_id: The access key ID to use for authentication.
68
+ secret_access_key: The secret access key to use for authentication.
69
+ session_token: The session token to use for authentication.
70
+ target_platform: A `Platform` to index dependencies for.
71
+ repodata_patch: The name of the conda package (expected to be in the `noarch` subdir) that should be used for repodata patching.
72
72
  force: Whether to forcefully re-index all subdirs.
73
73
  max_parallel: The maximum number of packages to process in-memory simultaneously.
74
74
  """
@@ -1,10 +1,10 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING, Optional
3
- from rattler.channel.channel import Channel
4
2
 
5
- from rattler.rattler import PyMatchSpec
3
+ from typing import TYPE_CHECKING, Optional
6
4
 
5
+ from rattler.channel.channel import Channel
7
6
  from rattler.package.package_name import PackageName
7
+ from rattler.rattler import PyMatchSpec
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from rattler.match_spec import NamelessMatchSpec
@@ -91,6 +91,8 @@ class MatchSpec:
91
91
  MatchSpec("pip >=24.0")
92
92
  >>> MatchSpec("pip 24")
93
93
  MatchSpec("pip ==24")
94
+ >>> MatchSpec('python[license=MIT]')
95
+ MatchSpec("python[license="MIT"]")
94
96
  >>>
95
97
  ```
96
98
  """
@@ -98,7 +100,7 @@ class MatchSpec:
98
100
  self._match_spec = PyMatchSpec(spec, strict)
99
101
  else:
100
102
  raise TypeError(
101
- "MatchSpec constructor received unsupported type" f" {type(spec).__name__!r} for the 'spec' parameter"
103
+ f"MatchSpec constructor received unsupported type {type(spec).__name__!r} for the 'spec' parameter"
102
104
  )
103
105
 
104
106
  @property
@@ -207,6 +209,25 @@ class MatchSpec:
207
209
  """
208
210
  return cls._from_py_match_spec(PyMatchSpec.from_nameless(spec._nameless_match_spec, name))
209
211
 
212
+ @classmethod
213
+ def from_url(cls, url: str) -> MatchSpec:
214
+ """
215
+ Constructs a MatchSpec from a URL.
216
+
217
+ Examples
218
+ --------
219
+ ```python
220
+ >>> MatchSpec.from_url('https://repo.anaconda.com/pkgs/main/linux-64/python-3.9.0-h3.tar.bz2')
221
+ MatchSpec("python[url="https://repo.anaconda.com/pkgs/main/linux-64/python-3.9.0-h3.tar.bz2"]")
222
+ >>> MatchSpec.from_url('https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81')
223
+ MatchSpec("_libgcc_mutex[md5="d7c89558ba9fa0495403155b64376d81", url="https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2"]")
224
+ >>> MatchSpec.from_url('https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#sha256:adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91')
225
+ MatchSpec("_libgcc_mutex[sha256="adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91", url="https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2"]")
226
+ >>>
227
+ ```
228
+ """
229
+ return cls._from_py_match_spec(PyMatchSpec.from_url(url))
230
+
210
231
  def __str__(self) -> str:
211
232
  """
212
233
  Returns a string representation of the MatchSpec.
@@ -9,6 +9,7 @@ from rattler.package.paths_json import (
9
9
  FileMode,
10
10
  )
11
11
  from rattler.package.index_json import IndexJson
12
+ from rattler.package.no_arch_type import NoArchType, NoArchLiteral
12
13
 
13
14
  __all__ = [
14
15
  "PackageName",
@@ -20,4 +21,6 @@ __all__ = [
20
21
  "PrefixPlaceholder",
21
22
  "FileMode",
22
23
  "IndexJson",
24
+ "NoArchLiteral",
25
+ "NoArchType",
23
26
  ]
@@ -75,7 +75,7 @@ class AboutJson:
75
75
  return AboutJson._from_py_about_json(PyAboutJson.from_str(string))
76
76
 
77
77
  @staticmethod
78
- def package_path() -> str:
78
+ def package_path() -> Path:
79
79
  """
80
80
  Returns the path to the file within the Conda archive.
81
81
 
@@ -85,7 +85,7 @@ class AboutJson:
85
85
  Examples
86
86
  --------
87
87
  ```python
88
- >>> AboutJson.package_path()
88
+ >>> str(AboutJson.package_path())
89
89
  'info/about.json'
90
90
  >>>
91
91
  ```
@@ -68,7 +68,7 @@ class IndexJson:
68
68
  return IndexJson._from_py_index_json(PyIndexJson.from_str(string))
69
69
 
70
70
  @staticmethod
71
- def package_path() -> str:
71
+ def package_path() -> Path:
72
72
  """
73
73
  Returns the path to the file within the Conda archive.
74
74
 
@@ -1,23 +1,23 @@
1
1
  from __future__ import annotations
2
- from typing import Optional
2
+ from typing import Literal, Optional
3
3
 
4
4
  from rattler.rattler import PyNoArchType
5
5
 
6
+ NoArchLiteral = Optional[Literal["python", "generic", True]]
7
+
6
8
 
7
9
  class NoArchType:
8
10
  _noarch: PyNoArchType
9
11
 
10
- def __init__(self, noarch: Optional[str] = None) -> None:
12
+ def __init__(self, noarch: NoArchLiteral = None) -> None:
11
13
  if noarch is None:
12
14
  self._noarch = PyNoArchType.none()
13
15
  elif noarch == "python":
14
16
  self._noarch = PyNoArchType.python()
15
- elif noarch == "generic":
17
+ elif noarch == "generic" or noarch is True:
16
18
  self._noarch = PyNoArchType.generic()
17
19
  else:
18
- raise ValueError(
19
- "NoArchType constructor received unsupported value " f"{noarch} for the `noarch` parameter"
20
- )
20
+ raise ValueError(f"NoArchType constructor received unsupported value {noarch} for the `noarch` parameter")
21
21
 
22
22
  @classmethod
23
23
  def _from_py_no_arch_type(cls, py_no_arch_type: PyNoArchType) -> NoArchType:
@@ -82,7 +82,7 @@ class PathsJson:
82
82
  return PathsJson._from_py_paths_json(PyPathsJson.from_str(string))
83
83
 
84
84
  @staticmethod
85
- def package_path() -> str:
85
+ def package_path() -> Path:
86
86
  """
87
87
  Returns the path to the file within the Conda archive.
88
88
 
@@ -224,7 +224,7 @@ class PathsEntry:
224
224
  ... sha256=None,
225
225
  ... size_in_bytes=None
226
226
  ... )
227
- >>> entry.relative_path
227
+ >>> str(entry.relative_path)
228
228
  'lib/file.txt'
229
229
  >>> entry.no_link
230
230
  False
@@ -254,7 +254,7 @@ class PathsEntry:
254
254
  self._inner = PyPathsEntry(relative_path, no_link, path_type._inner, prefix_placeholder, sha256, size_in_bytes)
255
255
 
256
256
  @property
257
- def relative_path(self) -> str:
257
+ def relative_path(self) -> Path:
258
258
  """
259
259
  The relative path from the root of the package.
260
260
 
@@ -265,10 +265,10 @@ class PathsEntry:
265
265
  ... "../test-data/conda-22.9.0-py38haa244fe_2-paths.json"
266
266
  ... )
267
267
  >>> entry = paths_json.paths[0]
268
- >>> entry.relative_path
268
+ >>> str(entry.relative_path)
269
269
  'Lib/site-packages/conda-22.9.0-py3.8.egg-info/PKG-INFO'
270
270
  >>> entry.relative_path = "new/path"
271
- >>> entry.relative_path
271
+ >>> str(entry.relative_path)
272
272
  'new/path'
273
273
  >>>
274
274
  ```
@@ -118,7 +118,7 @@ class RunExportsJson:
118
118
  return RunExportsJson._from_py_run_exports_json(PyRunExportsJson.from_str(string))
119
119
 
120
120
  @staticmethod
121
- def package_path() -> str:
121
+ def package_path() -> Path:
122
122
  """
123
123
  Returns the path to the file within the Conda archive.
124
124
 
@@ -35,13 +35,15 @@ class PlatformSingleton(type):
35
35
  try:
36
36
  return cls._instances[platform]
37
37
  except KeyError:
38
- instance = super().__call__(platform, *args, **kwargs)
39
- cls._instances[platform] = instance
40
- return instance
38
+ pass
39
+
40
+ instance = super().__call__(platform, *args, **kwargs)
41
+ cls._instances[platform] = instance
42
+ return instance
41
43
 
42
44
 
43
45
  class Platform(metaclass=PlatformSingleton):
44
- def __init__(self, value: PlatformLiteral):
46
+ def __init__(self, value: PlatformLiteral | str):
45
47
  self._inner = PyPlatform(value)
46
48
 
47
49
  @classmethod
@@ -159,7 +161,7 @@ class Platform(metaclass=PlatformSingleton):
159
161
  return self._inner.is_unix
160
162
 
161
163
  @property
162
- def arch(self) -> Arch:
164
+ def arch(self) -> Optional[Arch]:
163
165
  """
164
166
  Return the architecture of the platform.
165
167
 
@@ -173,7 +175,8 @@ class Platform(metaclass=PlatformSingleton):
173
175
  >>>
174
176
  ```
175
177
  """
176
- return Arch._from_py_arch(self._inner.arch())
178
+ arch = self._inner.arch()
179
+ return Arch._from_py_arch(arch) if arch is not None else None
177
180
 
178
181
  @property
179
182
  def only_platform(self) -> Optional[str]:
@@ -1,4 +1,4 @@
1
- from rattler.prefix.prefix_record import PrefixRecord
1
+ from rattler.prefix.prefix_record import PrefixRecord, Link, LinkType
2
2
  from rattler.prefix.prefix_paths import PrefixPaths, PrefixPathsEntry, PrefixPathType
3
3
 
4
- __all__ = ["PrefixRecord", "PrefixPaths", "PrefixPathsEntry", "PrefixPathType"]
4
+ __all__ = ["PrefixRecord", "PrefixPaths", "PrefixPathsEntry", "PrefixPathType", "Link", "LinkType"]
@@ -22,9 +22,9 @@ class PrefixPathType:
22
22
  "softlink",
23
23
  "directory",
24
24
  "pyc_file",
25
- "windows_python_entrypoint_script",
26
- "windows_python_entrypoint_exe",
27
- "unix_python_entrypoint",
25
+ "windows_python_entry_point_script",
26
+ "windows_python_entry_point_exe",
27
+ "unix_python_entry_point",
28
28
  ],
29
29
  ) -> None:
30
30
  """
@@ -82,25 +82,25 @@ class PrefixPathType:
82
82
  return self._inner.pyc_file
83
83
 
84
84
  @property
85
- def windows_python_entrypoint_script(self) -> bool:
85
+ def windows_python_entry_point_script(self) -> bool:
86
86
  """
87
87
  A Windows entry point python script (a <entrypoint>-script.py Python script file)
88
88
  """
89
- return self._inner.windows_python_entrypoint_script
89
+ return self._inner.windows_python_entry_point_script
90
90
 
91
91
  @property
92
- def windows_python_entrypoint_exe(self) -> bool:
92
+ def windows_python_entry_point_exe(self) -> bool:
93
93
  """
94
94
  A Windows entry point python script (a <entrypoint>.exe executable)
95
95
  """
96
- return self._inner.windows_python_entrypoint_exe
96
+ return self._inner.windows_python_entry_point_exe
97
97
 
98
98
  @property
99
- def unix_python_entrypoint(self) -> bool:
99
+ def unix_python_entry_point(self) -> bool:
100
100
  """
101
101
  A Unix entry point python script (a <entrypoint> Python script file)
102
102
  """
103
- return self._inner.unix_python_entrypoint
103
+ return self._inner.unix_python_entry_point
104
104
 
105
105
 
106
106
  class PrefixPathsEntry(BasePathLike):
@@ -1,10 +1,26 @@
1
1
  from __future__ import annotations
2
2
  import os
3
+ from enum import Enum
3
4
  from typing import List, Optional
4
5
 
5
- from rattler.rattler import PyRecord
6
+ from rattler.rattler import PyRecord, PyLink
6
7
  from rattler.prefix.prefix_paths import PrefixPaths
7
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)
8
24
 
9
25
 
10
26
  class PrefixRecord(RepoDataRecord):
@@ -22,6 +38,7 @@ class PrefixRecord(RepoDataRecord):
22
38
  self,
23
39
  repodata_record: RepoDataRecord,
24
40
  paths_data: PrefixPaths,
41
+ link: Optional[Link] = None,
25
42
  package_tarball_full_path: Optional[os.PathLike[str]] = None,
26
43
  extracted_package_dir: Optional[os.PathLike[str]] = None,
27
44
  requested_spec: Optional[str] = None,
@@ -30,6 +47,7 @@ class PrefixRecord(RepoDataRecord):
30
47
  record = PyRecord.create_prefix_record(
31
48
  repodata_record._record,
32
49
  paths_data._paths,
50
+ link._inner if link else None,
33
51
  package_tarball_full_path,
34
52
  extracted_package_dir,
35
53
  requested_spec,
@@ -61,7 +79,7 @@ class PrefixRecord(RepoDataRecord):
61
79
  self._record.write_to_path(path, pretty)
62
80
 
63
81
  @property
64
- def package_tarball_full_path(self) -> Optional[os.PathLike[str]]:
82
+ def package_tarball_full_path(self) -> Optional[Path]:
65
83
  """
66
84
  The path to where the archive of the package was stored on disk.
67
85
 
@@ -71,7 +89,7 @@ class PrefixRecord(RepoDataRecord):
71
89
  >>> r = PrefixRecord.from_path(
72
90
  ... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
73
91
  ... )
74
- >>> r.package_tarball_full_path
92
+ >>> str(r.package_tarball_full_path)
75
93
  'C:\\\\Users\\\\bas\\\\micromamba\\\\pkgs\\\\requests-2.28.2-pyhd8ed1ab_0.tar.bz2'
76
94
  >>>
77
95
  ```
@@ -83,7 +101,7 @@ class PrefixRecord(RepoDataRecord):
83
101
  self._record.package_tarball_full_path = value
84
102
 
85
103
  @property
86
- def extracted_package_dir(self) -> Optional[os.PathLike[str]]:
104
+ def extracted_package_dir(self) -> Optional[Path]:
87
105
  """
88
106
  The path that contains the extracted package content.
89
107
 
@@ -93,7 +111,7 @@ class PrefixRecord(RepoDataRecord):
93
111
  >>> r = PrefixRecord.from_path(
94
112
  ... "../test-data/conda-meta/requests-2.28.2-pyhd8ed1ab_0.json"
95
113
  ... )
96
- >>> r.extracted_package_dir
114
+ >>> str(r.extracted_package_dir)
97
115
  'C:\\\\Users\\\\bas\\\\micromamba\\\\pkgs\\\\requests-2.28.2-pyhd8ed1ab_0'
98
116
  >>>
99
117
  ```
@@ -105,7 +123,7 @@ class PrefixRecord(RepoDataRecord):
105
123
  self._record.extracted_package_dir = value
106
124
 
107
125
  @property
108
- def files(self) -> List[os.PathLike[str]]:
126
+ def files(self) -> List[Path]:
109
127
  """
110
128
  A sorted list of all files included in this package
111
129
 
rattler/rattler.abi3.so CHANGED
Binary file
@@ -2,7 +2,7 @@ from rattler.repo_data.package_record import PackageRecord
2
2
  from rattler.repo_data.repo_data import RepoData
3
3
  from rattler.repo_data.patch_instructions import PatchInstructions
4
4
  from rattler.repo_data.record import RepoDataRecord
5
- from rattler.repo_data.sparse import SparseRepoData
5
+ from rattler.repo_data.sparse import SparseRepoData, PackageFormatSelection
6
6
  from rattler.repo_data.gateway import Gateway, SourceConfig
7
7
 
8
8
  __all__ = [
@@ -13,4 +13,5 @@ __all__ = [
13
13
  "SparseRepoData",
14
14
  "Gateway",
15
15
  "SourceConfig",
16
+ "PackageFormatSelection",
16
17
  ]
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import os
4
- from typing import Optional, List
4
+ from typing import Optional, List, Iterable
5
5
  from dataclasses import dataclass
6
6
 
7
7
  from rattler.rattler import PyGateway, PySourceConfig, PyMatchSpec
@@ -126,9 +126,9 @@ class Gateway:
126
126
 
127
127
  async def query(
128
128
  self,
129
- channels: List[Channel | str],
130
- platforms: List[Platform | PlatformLiteral],
131
- specs: List[MatchSpec | PackageName | str],
129
+ channels: Iterable[Channel | str],
130
+ platforms: Iterable[Platform | PlatformLiteral],
131
+ specs: Iterable[MatchSpec | PackageName | str],
132
132
  recursive: bool = True,
133
133
  ) -> List[List[RepoDataRecord]]:
134
134
  """Queries the gateway for repodata.
@@ -183,7 +183,7 @@ class Gateway:
183
183
  return [[RepoDataRecord._from_py_record(record) for record in records] for records in py_records]
184
184
 
185
185
  async def names(
186
- self, channels: List[Channel | str], platforms: List[Platform | PlatformLiteral]
186
+ self, channels: List[Channel | str], platforms: Iterable[Platform | PlatformLiteral]
187
187
  ) -> List[PackageName]:
188
188
  """Queries all the names of packages in a channel.
189
189
 
@@ -220,7 +220,7 @@ class Gateway:
220
220
  return [PackageName._from_py_package_name(package_name) for package_name in py_package_names]
221
221
 
222
222
  def clear_repodata_cache(
223
- self, channel: Channel | str, subdirs: Optional[List[Platform | PlatformLiteral]] = None
223
+ self, channel: Channel | str, subdirs: Optional[Iterable[Platform | PlatformLiteral]] = None
224
224
  ) -> None:
225
225
  """
226
226
  Clears any in-memory cache for the given channel.
@@ -5,10 +5,10 @@ import datetime
5
5
 
6
6
  from rattler import VersionWithSource
7
7
  from rattler.match_spec.match_spec import MatchSpec
8
- from rattler.package.no_arch_type import NoArchType
8
+ from rattler.package.no_arch_type import NoArchType, NoArchLiteral
9
9
  from rattler.package.package_name import PackageName
10
10
  from rattler.platform.platform import Platform
11
- from rattler.rattler import PyRecord
11
+ from rattler.rattler import PyRecord, ParsePlatformError
12
12
 
13
13
  if TYPE_CHECKING:
14
14
  import networkx as nx
@@ -189,9 +189,9 @@ class PackageRecord:
189
189
  build: str,
190
190
  build_number: int,
191
191
  subdir: str | Platform,
192
- arch: Optional[str],
193
- platform: Optional[str],
194
- noarch: Optional[NoArchType] = None,
192
+ arch: Optional[str] = None,
193
+ platform: Optional[str] = None,
194
+ noarch: Optional[NoArchType | NoArchLiteral] = None,
195
195
  depends: Optional[List[str]] = None,
196
196
  constrains: Optional[List[str]] = None,
197
197
  sha256: Optional[bytes] = None,
@@ -204,11 +204,18 @@ class PackageRecord:
204
204
  license_family: Optional[str] = None,
205
205
  python_site_packages_path: Optional[str] = None,
206
206
  ) -> None:
207
- # Convert Platform to str
207
+ if isinstance(subdir, str):
208
+ try:
209
+ subdir = Platform(subdir)
210
+ except ParsePlatformError:
211
+ # if the string is not a valid platform, we just keep it as a string
212
+ pass
213
+
208
214
  if isinstance(subdir, Platform):
209
- arch = str(subdir.arch)
210
- platform = subdir.only_platform
211
- subdir = str(subdir)
215
+ if arch is None:
216
+ subdir_arch = subdir.arch
217
+ arch = str(subdir_arch) if subdir_arch is not None else arch
218
+ platform = subdir.only_platform if platform is None else platform
212
219
 
213
220
  # convert str to PackageName
214
221
  if isinstance(name, str):
@@ -218,15 +225,18 @@ class PackageRecord:
218
225
  if isinstance(version, str):
219
226
  version = VersionWithSource(version)
220
227
 
228
+ if not isinstance(noarch, NoArchType):
229
+ noarch = NoArchType(noarch)
230
+
221
231
  self._record = PyRecord.create(
222
232
  name._name,
223
233
  (version._version, version._source),
224
234
  build,
225
235
  build_number,
226
- subdir,
227
- arch,
236
+ str(subdir),
237
+ str(arch) if arch is not None else None,
228
238
  platform,
229
- noarch,
239
+ noarch._noarch,
230
240
  python_site_packages_path,
231
241
  )
232
242
 
@@ -1,14 +1,44 @@
1
1
  from __future__ import annotations
2
2
  import os
3
3
  from pathlib import Path
4
- from typing import List
4
+ from typing import List, Optional, Type, Literal, Iterable
5
+ from types import TracebackType
6
+
7
+ from rattler.match_spec.match_spec import MatchSpec
5
8
  from rattler.channel.channel import Channel
6
9
  from rattler.package.package_name import PackageName
10
+ from enum import Enum
7
11
 
8
- from rattler.rattler import PySparseRepoData
12
+ from rattler.rattler import PySparseRepoData, PyPackageFormatSelection
9
13
  from rattler.repo_data.record import RepoDataRecord
10
14
 
11
15
 
16
+ class PackageFormatSelection(Enum):
17
+ """
18
+ Enum that describes what to do if both a `.tar.bz2` and a `.conda` package is available.
19
+ """
20
+
21
+ ONLY_TAR_BZ2 = PyPackageFormatSelection.OnlyTarBz2
22
+ """
23
+ Only use the `.tar.bz2` packages, ignore all `.conda` packages.
24
+ """
25
+
26
+ ONLY_CONDA = PyPackageFormatSelection.OnlyConda
27
+ """
28
+ Only use the `.conda` packages, ignore all `.tar.bz2` packages.
29
+ """
30
+
31
+ PREFER_CONDA = PyPackageFormatSelection.PreferConda
32
+ """
33
+ Only use the `.conda` packages if there are both a `.tar.bz2` and a `.conda` package available.
34
+ """
35
+
36
+ BOTH = PyPackageFormatSelection.Both
37
+ """
38
+ Use both the `.tar.bz2` and the `.conda` packages.
39
+ """
40
+
41
+
12
42
  class SparseRepoData:
13
43
  """
14
44
  A class to enable loading records from a `repodata.json` file on demand.
@@ -39,7 +69,43 @@ class SparseRepoData:
39
69
  )
40
70
  self._sparse = PySparseRepoData(channel._channel, subdir, str(path))
41
71
 
42
- def package_names(self) -> List[str]:
72
+ def close(self) -> None:
73
+ """
74
+ Closes any mapped resources associated with this `SparseRepoData`
75
+ instance. It is good practice to call this method when you are done
76
+ with it. This is especially important if you want to modify or delete
77
+ the file from which this instance was created.
78
+
79
+ This method will release all resources associated with this instance,
80
+ including those that are currently being used on another thread. This
81
+ method will block until all resources are released.
82
+
83
+ This method has no effect if the file is already closed. Once the
84
+ instance is closed, any operation on the instance will raise a
85
+ `ValueError`.
86
+
87
+ As a convenience, it is allowed to call this method more than once;
88
+ only the first call, however, will have an effect.
89
+
90
+ Examples
91
+ --------
92
+ ```python
93
+ >>> from rattler import Channel, ChannelConfig
94
+ >>> channel = Channel("dummy", ChannelConfig())
95
+ >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
96
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
97
+ >>> sparse_data.close()
98
+ >>> sparse_data.package_names() # doctest: +IGNORE_EXCEPTION_DETAIL
99
+ Traceback (most recent call last):
100
+ ValueError: I/O operation on closed file.
101
+ >>>
102
+ ```
103
+ """
104
+ self._sparse.close()
105
+
106
+ def package_names(
107
+ self, package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA
108
+ ) -> List[str]:
43
109
  """
44
110
  Returns a list over all package names in this repodata file.
45
111
  This works by iterating over all elements in the `packages` and
@@ -51,9 +117,8 @@ class SparseRepoData:
51
117
  ```python
52
118
  >>> from rattler import Channel, ChannelConfig
53
119
  >>> channel = Channel("dummy", ChannelConfig())
54
- >>> subdir = "test-data/dummy/noarch"
55
120
  >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
56
- >>> sparse_data = SparseRepoData(channel, subdir, path)
121
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
57
122
  >>> package_names = sparse_data.package_names()
58
123
  >>> package_names
59
124
  [...]
@@ -62,9 +127,22 @@ class SparseRepoData:
62
127
  >>>
63
128
  ```
64
129
  """
65
- return self._sparse.package_names()
130
+ return self._sparse.package_names(package_format_selection.value)
131
+
132
+ def record_count(
133
+ self, package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA
134
+ ) -> int:
135
+ """
136
+ Returns the total number of packages in this repodata file.
137
+ :return:
138
+ """
139
+ return self._sparse.record_count(package_format_selection.value)
66
140
 
67
- def load_records(self, package_name: PackageName) -> List[RepoDataRecord]:
141
+ def load_records(
142
+ self,
143
+ package_name: str | PackageName,
144
+ package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA,
145
+ ) -> List[RepoDataRecord]:
68
146
  """
69
147
  Returns all the records for the specified package name.
70
148
 
@@ -73,9 +151,8 @@ class SparseRepoData:
73
151
  ```python
74
152
  >>> from rattler import Channel, ChannelConfig, RepoDataRecord, PackageName
75
153
  >>> channel = Channel("dummy", ChannelConfig())
76
- >>> subdir = "test-data/dummy/noarch"
77
154
  >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
78
- >>> sparse_data = SparseRepoData(channel, subdir, path)
155
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
79
156
  >>> package_name = PackageName(sparse_data.package_names()[0])
80
157
  >>> records = sparse_data.load_records(package_name)
81
158
  >>> records
@@ -85,8 +162,66 @@ class SparseRepoData:
85
162
  >>>
86
163
  ```
87
164
  """
165
+ if not isinstance(package_name, PackageName):
166
+ package_name = PackageName(package_name)
167
+ return [
168
+ RepoDataRecord._from_py_record(record)
169
+ for record in self._sparse.load_records(package_name._name, package_format_selection.value)
170
+ ]
171
+
172
+ def load_all_records(
173
+ self, package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA
174
+ ) -> List[RepoDataRecord]:
175
+ """
176
+ Returns all the records for the specified package name.
177
+
178
+ Examples
179
+ --------
180
+ ```python
181
+ >>> from rattler import Channel, ChannelConfig, RepoDataRecord, PackageName
182
+ >>> channel = Channel("dummy", ChannelConfig())
183
+ >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
184
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
185
+ >>> records = sparse_data.load_all_records()
186
+ >>> records
187
+ [...]
188
+ >>> isinstance(records[0], RepoDataRecord)
189
+ True
190
+ >>>
191
+ ```
192
+ """
88
193
  # maybe change package_name to Union[str, PackageName]
89
- return [RepoDataRecord._from_py_record(record) for record in self._sparse.load_records(package_name._name)]
194
+ return [
195
+ RepoDataRecord._from_py_record(record)
196
+ for record in self._sparse.load_all_records(package_format_selection.value)
197
+ ]
198
+
199
+ def load_matching_records(
200
+ self,
201
+ specs: Iterable[MatchSpec],
202
+ package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA,
203
+ ) -> List[RepoDataRecord]:
204
+ """
205
+ Returns all the records that match any of the specified MatchSpecs.
206
+
207
+ Examples
208
+ --------
209
+ ```python
210
+ >>> from rattler import Channel, ChannelConfig, RepoDataRecord, PackageName
211
+ >>> channel = Channel("dummy", ChannelConfig())
212
+ >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
213
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
214
+ >>> [record.file_name for record in sparse_data.load_matching_records([MatchSpec("* 12.5")])]
215
+ ['cuda-version-12.5-hd4f0392_3.conda']
216
+ >>>
217
+ ```
218
+ """
219
+ return [
220
+ RepoDataRecord._from_py_record(record)
221
+ for record in self._sparse.load_matching_records(
222
+ [spec._match_spec for spec in specs], package_format_selection.value
223
+ )
224
+ ]
90
225
 
91
226
  @property
92
227
  def subdir(self) -> str:
@@ -98,11 +233,10 @@ class SparseRepoData:
98
233
  ```python
99
234
  >>> from rattler import Channel, ChannelConfig
100
235
  >>> channel = Channel("dummy", ChannelConfig())
101
- >>> subdir = "test-data/dummy/noarch"
102
236
  >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
103
- >>> sparse_data = SparseRepoData(channel, subdir, path)
237
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
104
238
  >>> sparse_data.subdir
105
- 'test-data/dummy/noarch'
239
+ 'linux-64'
106
240
  >>>
107
241
  ```
108
242
  """
@@ -112,6 +246,7 @@ class SparseRepoData:
112
246
  def load_records_recursive(
113
247
  repo_data: List[SparseRepoData],
114
248
  package_names: List[PackageName],
249
+ package_format_selection: PackageFormatSelection = PackageFormatSelection.PREFER_CONDA,
115
250
  ) -> List[List[RepoDataRecord]]:
116
251
  """
117
252
  Given a set of [`SparseRepoData`]s load all the records
@@ -127,7 +262,7 @@ class SparseRepoData:
127
262
  >>> channel = Channel("dummy")
128
263
  >>> subdir = "test-data/dummy/linux-64"
129
264
  >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
130
- >>> sparse_data = SparseRepoData(channel, subdir, path)
265
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
131
266
  >>> package_name = PackageName("python")
132
267
  >>> SparseRepoData.load_records_recursive([sparse_data], [package_name])
133
268
  [...]
@@ -137,8 +272,7 @@ class SparseRepoData:
137
272
  return [
138
273
  [RepoDataRecord._from_py_record(record) for record in list_of_records]
139
274
  for list_of_records in PySparseRepoData.load_records_recursive(
140
- [r._sparse for r in repo_data],
141
- [p._name for p in package_names],
275
+ [r._sparse for r in repo_data], [p._name for p in package_names], package_format_selection.value
142
276
  )
143
277
  ]
144
278
 
@@ -160,12 +294,57 @@ class SparseRepoData:
160
294
  ```python
161
295
  >>> from rattler import Channel, ChannelConfig
162
296
  >>> channel = Channel("dummy", ChannelConfig())
163
- >>> subdir = "test-data/dummy/noarch"
164
297
  >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
165
- >>> sparse_data = SparseRepoData(channel, subdir, path)
298
+ >>> sparse_data = SparseRepoData(channel, "linux-64", path)
166
299
  >>> sparse_data
167
- SparseRepoData(subdir="test-data/dummy/noarch")
300
+ SparseRepoData(subdir="linux-64")
168
301
  >>>
169
302
  ```
170
303
  """
171
304
  return f'SparseRepoData(subdir="{self.subdir}")'
305
+
306
+ def __enter__(self) -> SparseRepoData:
307
+ """
308
+ Returns the `SparseRepoData` instance itself. This is used to
309
+ enable the use of the `with` statement to automatically close
310
+ the instance when done.
311
+
312
+ Examples
313
+ --------
314
+ ```python
315
+ >>> from rattler import Channel, ChannelConfig
316
+ >>> channel = Channel("dummy", ChannelConfig())
317
+ >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
318
+ >>> with SparseRepoData(channel, "linux-64", path) as sparse_data:
319
+ ... print(sparse_data)
320
+ ...
321
+ SparseRepoData(subdir="linux-64")
322
+ >>>
323
+ ```
324
+ """
325
+ return self
326
+
327
+ def __exit__(
328
+ self,
329
+ exctype: Optional[Type[BaseException]],
330
+ excinst: Optional[BaseException],
331
+ exctb: Optional[TracebackType],
332
+ ) -> Literal[False]:
333
+ """
334
+ Closes the `SparseRepoData` instance when exiting the `with` statement.
335
+
336
+ Examples
337
+ --------
338
+ ```python
339
+ >>> from rattler import Channel, ChannelConfig
340
+ >>> channel = Channel("dummy", ChannelConfig())
341
+ >>> path = "../test-data/channels/dummy/linux-64/repodata.json"
342
+ >>> with SparseRepoData(channel, "linux-64", path) as sparse_data:
343
+ ... print(sparse_data)
344
+ ...
345
+ SparseRepoData(subdir="linux-64")
346
+ >>>
347
+ ```
348
+ """
349
+ self.close()
350
+ return False
rattler/solver/solver.py CHANGED
@@ -6,7 +6,7 @@ from rattler import Channel, Platform, VirtualPackage, SparseRepoData
6
6
  from rattler.match_spec.match_spec import MatchSpec
7
7
 
8
8
  from rattler.channel import ChannelPriority
9
- from rattler.rattler import py_solve, PyMatchSpec, py_solve_with_sparse_repodata
9
+ from rattler.rattler import py_solve, PyMatchSpec, py_solve_with_sparse_repodata, PyPackageFormatSelection
10
10
 
11
11
  from rattler.platform.platform import PlatformLiteral
12
12
  from rattler.repo_data.gateway import Gateway
@@ -127,6 +127,7 @@ async def solve_with_sparse_repodata(
127
127
  exclude_newer: Optional[datetime.datetime] = None,
128
128
  strategy: SolveStrategy = "highest",
129
129
  constraints: Optional[Sequence[MatchSpec | str]] = None,
130
+ use_only_tar_bz2: bool = False,
130
131
  ) -> List[RepoDataRecord]:
131
132
  """
132
133
  Resolve the dependencies and return the `RepoDataRecord`s
@@ -171,6 +172,7 @@ async def solve_with_sparse_repodata(
171
172
  constraints: Additional constraints that should be satisfied by the solver.
172
173
  Packages included in the `constraints` are not necessarily installed,
173
174
  but they must be satisfied by the solution.
175
+ use_only_tar_bz2: If `True` only `.tar.bz2` packages are used. If `False` `.conda` packages are preferred.
174
176
 
175
177
  Returns:
176
178
  Resolved list of `RepoDataRecord`s.
@@ -191,6 +193,9 @@ async def solve_with_sparse_repodata(
191
193
  ],
192
194
  channel_priority=channel_priority.value,
193
195
  timeout=int(timeout / datetime.timedelta(microseconds=1)) if timeout else None,
196
+ package_format_selection=PyPackageFormatSelection.OnlyTarBz2
197
+ if use_only_tar_bz2
198
+ else PyPackageFormatSelection.PreferConda,
194
199
  exclude_newer_timestamp_ms=int(exclude_newer.replace(tzinfo=datetime.timezone.utc).timestamp() * 1000)
195
200
  if exclude_newer
196
201
  else None,
@@ -168,6 +168,8 @@ class VirtualPackage:
168
168
  """
169
169
  Returns virtual packages detected for the current system or an error
170
170
  if the versions could not be properly detected.
171
+
172
+ .. deprecated:: 0.7.0 Use `detect` instead.
171
173
  """
172
174
  warnings.warn("Use `detect` instead")
173
175
  return VirtualPackage.detect()