dycw-utilities 0.176.4__py3-none-any.whl → 0.176.6__py3-none-any.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dycw-utilities
3
- Version: 0.176.4
3
+ Version: 0.176.6
4
4
  Summary: Miscellaneous Python utilities
5
5
  Author: Derek Wan
6
6
  Author-email: Derek Wan <d.wan@icloud.com>
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=SJhOje1TStT2FY-F-Dfs6lWe6hk-1K8sp3Q6dwJm87Y,60
1
+ utilities/__init__.py,sha256=30qJasMvZPS_VQwLBhylCmlhjcGr2IwhMF8Ehsdi7-M,60
2
2
  utilities/altair.py,sha256=TLfRFbG9HwG7SLXoJ-v0r-t49ZaGgTQZD82cpjVi4vs,9085
3
3
  utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
4
4
  utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
@@ -44,6 +44,7 @@ utilities/operator.py,sha256=C3NylZWGTVWRpwYHOPVhaLgRhw0DfpS4_XQ8KfPhBLQ,3613
44
44
  utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
45
45
  utilities/orjson.py,sha256=T_0SlK811ysg46d3orvIPY3JpBa4FRMpP2wlPQo7-gU,41854
46
46
  utilities/os.py,sha256=kjKKSQfnRqFTTZ315iavaaGd3gGuYNoSWlxVLCJjyQs,4852
47
+ utilities/packaging.py,sha256=UGD2O2kW8fRYCPpwrBS2qq1j-3f1WsYDkyvaP2bxg3s,3096
47
48
  utilities/parse.py,sha256=g7Qm9eBOIeDId2tGA021CIaeF6jp1TI8rx4srdvlyoo,17937
48
49
  utilities/pathlib.py,sha256=N4Ip8R9eCM-6GfvxUJ3T9oQIle2C2P52F-13BCFRdTg,9345
49
50
  utilities/permissions.py,sha256=vLXlWztSVYffbrxptne7ksj6dU1HLekm4fEvS4ny_4Q,8944
@@ -97,7 +98,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
97
98
  utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
98
99
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
99
100
  utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
100
- dycw_utilities-0.176.4.dist-info/WHEEL,sha256=RRVLqVugUmFOqBedBFAmA4bsgFcROUBiSUKlERi0Hcg,79
101
- dycw_utilities-0.176.4.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
102
- dycw_utilities-0.176.4.dist-info/METADATA,sha256=pJbc4nUEtf3VzoMYkgMGiVlgf1LAV6Yh9eVG-sG9ZVY,1398
103
- dycw_utilities-0.176.4.dist-info/RECORD,,
101
+ dycw_utilities-0.176.6.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
102
+ dycw_utilities-0.176.6.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
103
+ dycw_utilities-0.176.6.dist-info/METADATA,sha256=2x7y41YJEnsO9-W1RdfA0Ndxo7GSBDyS_Ip3uz4NazY,1398
104
+ dycw_utilities-0.176.6.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.21
2
+ Generator: uv 0.9.22
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.176.4"
3
+ __version__ = "0.176.6"
utilities/packaging.py ADDED
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import TYPE_CHECKING, Self, overload, override
5
+
6
+ import packaging._parser
7
+ import packaging.requirements
8
+ from packaging.requirements import _parse_requirement
9
+ from packaging.specifiers import Specifier, SpecifierSet
10
+
11
+ from utilities.iterables import OneEmptyError, one
12
+
13
+ if TYPE_CHECKING:
14
+ from packaging._parser import MarkerList
15
+
16
+
17
+ @dataclass(order=True, unsafe_hash=True, kw_only=True, slots=True)
18
+ class Requirement:
19
+ requirement: str
20
+ _parsed_req: packaging._parser.ParsedRequirement
21
+ _custom_req: _CustomRequirement
22
+
23
+ def __getitem__(self, operator: str, /) -> str:
24
+ return self.specifier_set[operator]
25
+
26
+ @override
27
+ def __str__(self) -> str:
28
+ return str(self._custom_req)
29
+
30
+ @classmethod
31
+ def new(cls, requirement: str, /) -> Self:
32
+ return cls(
33
+ requirement=requirement,
34
+ _parsed_req=_parse_requirement(requirement),
35
+ _custom_req=_CustomRequirement(requirement),
36
+ )
37
+
38
+ @property
39
+ def extras(self) -> list[str]:
40
+ return self._parsed_req.extras
41
+
42
+ @overload
43
+ def get(self, operator: str, default: str, /) -> str: ...
44
+ @overload
45
+ def get(self, operator: str, default: None = None, /) -> str | None: ...
46
+ def get(self, operator: str, default: str | None = None, /) -> str | None:
47
+ return self.specifier_set.get(operator, default)
48
+
49
+ @property
50
+ def marker(self) -> MarkerList | None:
51
+ return self._parsed_req.marker
52
+
53
+ @property
54
+ def name(self) -> str:
55
+ return self._parsed_req.name
56
+
57
+ @property
58
+ def specifier(self) -> str:
59
+ return self._parsed_req.specifier
60
+
61
+ @property
62
+ def specifier_set(self) -> _CustomSpecifierSet:
63
+ return _CustomSpecifierSet(_parse_requirement(self.requirement).specifier)
64
+
65
+ @property
66
+ def url(self) -> str:
67
+ return self._parsed_req.url
68
+
69
+
70
+ class _CustomRequirement(packaging.requirements.Requirement):
71
+ @override
72
+ def __init__(self, requirement_string: str) -> None:
73
+ super().__init__(requirement_string)
74
+ parsed = _parse_requirement(requirement_string)
75
+ self.specifier = _CustomSpecifierSet(parsed.specifier)
76
+
77
+
78
+ class _CustomSpecifierSet(SpecifierSet):
79
+ def __getitem__(self, operator: str, /) -> str:
80
+ try:
81
+ return one(s.version for s in self if s.operator == operator)
82
+ except OneEmptyError:
83
+ raise KeyError(operator) from None
84
+
85
+ @override
86
+ def __str__(self) -> str:
87
+ specs = sorted(self._specs, key=self._sort_key)
88
+ return ", ".join(map(str, specs))
89
+
90
+ @overload
91
+ def get(self, operator: str, default: str, /) -> str: ...
92
+ @overload
93
+ def get(self, operator: str, default: None = None, /) -> str | None: ...
94
+ def get(self, operator: str, default: str | None = None, /) -> str | None:
95
+ try:
96
+ return self[operator]
97
+ except KeyError:
98
+ return default
99
+
100
+ def _sort_key(self, spec: Specifier, /) -> int:
101
+ return [">=", "<"].index(spec.operator)
102
+
103
+
104
+ __all__ = ["Requirement"]