dycw-utilities 0.176.5__py3-none-any.whl → 0.177.0__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.5
3
+ Version: 0.177.0
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=chOgc1NV48pH7zK_NN0RHPlWQSfdIFGjwBbOXK_Es2A,60
1
+ utilities/__init__.py,sha256=RsM8wAOFee7SDF_pWygxynYpc3vDkccPqwghqyUS4wU,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,7 +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=kuGenKbyAwxZWL_mbkMzkNXKjhyi9a9tfZQwitrYYlM,2401
47
+ utilities/packaging.py,sha256=z_3v2ofEkqIMLhiEvP8zvQUaUFIqY6d-9XK_ZfsZTb0,3723
48
48
  utilities/parse.py,sha256=g7Qm9eBOIeDId2tGA021CIaeF6jp1TI8rx4srdvlyoo,17937
49
49
  utilities/pathlib.py,sha256=N4Ip8R9eCM-6GfvxUJ3T9oQIle2C2P52F-13BCFRdTg,9345
50
50
  utilities/permissions.py,sha256=vLXlWztSVYffbrxptne7ksj6dU1HLekm4fEvS4ny_4Q,8944
@@ -98,7 +98,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
98
98
  utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
99
99
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
100
100
  utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
101
- dycw_utilities-0.176.5.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
102
- dycw_utilities-0.176.5.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
103
- dycw_utilities-0.176.5.dist-info/METADATA,sha256=g6FzLC0r4g8uwbM_zouJhCaaHM0IsQ1q33xQyS5tZp0,1398
104
- dycw_utilities-0.176.5.dist-info/RECORD,,
101
+ dycw_utilities-0.177.0.dist-info/WHEEL,sha256=KSLUh82mDPEPk0Bx0ScXlWL64bc8KmzIPNcpQZFV-6E,79
102
+ dycw_utilities-0.177.0.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
103
+ dycw_utilities-0.177.0.dist-info/METADATA,sha256=s_2LJzGzSZmuxFdy-JTQqxGi-FJ0iiXla3SpYnoZdrI,1398
104
+ dycw_utilities-0.177.0.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.176.5"
3
+ __version__ = "0.177.0"
utilities/packaging.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Self, override
3
+ from dataclasses import dataclass, field
4
+ from typing import TYPE_CHECKING, Self, overload, override
5
5
 
6
6
  import packaging._parser
7
7
  import packaging.requirements
@@ -14,31 +14,34 @@ if TYPE_CHECKING:
14
14
  from packaging._parser import MarkerList
15
15
 
16
16
 
17
- @dataclass(order=True, unsafe_hash=True, kw_only=True, slots=True)
17
+ @dataclass(order=True, unsafe_hash=True, slots=True)
18
18
  class Requirement:
19
19
  requirement: str
20
- _parsed_req: packaging._parser.ParsedRequirement
21
- _custom_req: _CustomRequirement
20
+ _parsed_req: packaging._parser.ParsedRequirement = field(init=False, repr=False)
21
+ _custom_req: _CustomRequirement = field(init=False, repr=False)
22
22
 
23
- def __getitem__(self, key: str, /) -> str:
24
- return self.specifier_set[key]
23
+ def __getitem__(self, operator: str, /) -> str:
24
+ return self.specifier_set[operator]
25
+
26
+ def __post_init__(self) -> None:
27
+ self._parsed_req = _parse_requirement(self.requirement)
28
+ self._custom_req = _CustomRequirement(self.requirement)
25
29
 
26
30
  @override
27
31
  def __str__(self) -> str:
28
32
  return str(self._custom_req)
29
33
 
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
34
  @property
39
35
  def extras(self) -> list[str]:
40
36
  return self._parsed_req.extras
41
37
 
38
+ @overload
39
+ def get(self, operator: str, default: str, /) -> str: ...
40
+ @overload
41
+ def get(self, operator: str, default: None = None, /) -> str | None: ...
42
+ def get(self, operator: str, default: str | None = None, /) -> str | None:
43
+ return self.specifier_set.get(operator, default)
44
+
42
45
  @property
43
46
  def marker(self) -> MarkerList | None:
44
47
  return self._parsed_req.marker
@@ -47,6 +50,9 @@ class Requirement:
47
50
  def name(self) -> str:
48
51
  return self._parsed_req.name
49
52
 
53
+ def replace(self, operator: str, version: str, /) -> Self:
54
+ return type(self)(str(self._custom_req.replace(operator, version)))
55
+
50
56
  @property
51
57
  def specifier(self) -> str:
52
58
  return self._parsed_req.specifier
@@ -61,26 +67,48 @@ class Requirement:
61
67
 
62
68
 
63
69
  class _CustomRequirement(packaging.requirements.Requirement):
70
+ specifier: _CustomSpecifierSet
71
+
64
72
  @override
65
73
  def __init__(self, requirement_string: str) -> None:
66
74
  super().__init__(requirement_string)
67
75
  parsed = _parse_requirement(requirement_string)
68
- self.specifier = _CustomSpecifierSet(parsed.specifier)
76
+ self.specifier = _CustomSpecifierSet(parsed.specifier) # pyright: ignore[reportIncompatibleVariableOverride]
77
+
78
+ def replace(self, operator: str, version: str, /) -> Self:
79
+ new = type(self)(super().__str__())
80
+ new.specifier = self.specifier.replace(operator, version)
81
+ return new
69
82
 
70
83
 
71
84
  class _CustomSpecifierSet(SpecifierSet):
72
- def __getitem__(self, key: str, /) -> str:
85
+ def __getitem__(self, operator: str, /) -> str:
73
86
  try:
74
- return one(s.version for s in self if s.operator == key)
87
+ return one(s.version for s in self if s.operator == operator)
75
88
  except OneEmptyError:
76
- raise KeyError(key) from None
89
+ raise KeyError(operator) from None
77
90
 
78
91
  @override
79
92
  def __str__(self) -> str:
80
- specs = sorted(self._specs, key=self._key)
93
+ specs = sorted(self._specs, key=self._sort_key)
81
94
  return ", ".join(map(str, specs))
82
95
 
83
- def _key(self, spec: Specifier, /) -> int:
96
+ @overload
97
+ def get(self, operator: str, default: str, /) -> str: ...
98
+ @overload
99
+ def get(self, operator: str, default: None = None, /) -> str | None: ...
100
+ def get(self, operator: str, default: str | None = None, /) -> str | None:
101
+ try:
102
+ return self[operator]
103
+ except KeyError:
104
+ return default
105
+
106
+ def replace(self, operator: str, version: str, /) -> Self:
107
+ new = Specifier(spec=f"{operator}{version}")
108
+ remainder = (s for s in self if s.operator != operator)
109
+ return type(self)([new, *remainder])
110
+
111
+ def _sort_key(self, spec: Specifier, /) -> int:
84
112
  return [">=", "<"].index(spec.operator)
85
113
 
86
114