resourcecap 0.2.2__tar.gz → 0.2.3__tar.gz

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.4
2
2
  Name: resourcecap
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A python package to limit the resource usage of any program
5
5
  Author: purushottam-dafure
6
6
  Author-email: purushottam-dafure <purushottamdafure@gmail.com>
@@ -97,6 +97,17 @@ Each call to `foo()` logs something like:
97
97
  the above code will stop execution at that point and raise BudgetExhaustedError,
98
98
  after the 4th call to `foo()` pushes the spend from 30 to 40.
99
99
 
100
+ `BudgetExhaustedError` carries structured fields, not just a message, so you
101
+ can handle it programmatically without parsing text:
102
+
103
+ ```python
104
+ try:
105
+ with Budget(amount = 30):
106
+ [foo() for i in range(5)]
107
+ except BudgetExhaustedError as e:
108
+ print(e.resource, e.limit, e.spent) # "cost" 30 40.0
109
+ ```
110
+
100
111
  A `Budget` instance can be reused across separate, non-overlapping `with`
101
112
  blocks (its spend resets each time), but it can't be open twice at once —
102
113
  entering it while it's already open, from a concurrent task/thread or
@@ -83,6 +83,17 @@ Each call to `foo()` logs something like:
83
83
  the above code will stop execution at that point and raise BudgetExhaustedError,
84
84
  after the 4th call to `foo()` pushes the spend from 30 to 40.
85
85
 
86
+ `BudgetExhaustedError` carries structured fields, not just a message, so you
87
+ can handle it programmatically without parsing text:
88
+
89
+ ```python
90
+ try:
91
+ with Budget(amount = 30):
92
+ [foo() for i in range(5)]
93
+ except BudgetExhaustedError as e:
94
+ print(e.resource, e.limit, e.spent) # "cost" 30 40.0
95
+ ```
96
+
86
97
  A `Budget` instance can be reused across separate, non-overlapping `with`
87
98
  blocks (its spend resets each time), but it can't be open twice at once —
88
99
  entering it while it's already open, from a concurrent task/thread or
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "resourcecap"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "A python package to limit the resource usage of any program"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "resourcecap"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "A python package to limit the resource usage of any program"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -11,7 +11,19 @@ logger = logging.getLogger("resourcecap")
11
11
 
12
12
 
13
13
  class BudgetExhaustedError(Exception):
14
- """Raised when a `Budget`'s limit for some resource is exceeded."""
14
+ """Raised when a `Budget`'s limit for some resource is exceeded.
15
+
16
+ Attributes:
17
+ resource: the key of the resource whose limit was exceeded.
18
+ limit: that resource's limit.
19
+ spent: how much had been spent when the limit was exceeded.
20
+ """
21
+
22
+ def __init__(self, resource: Hashable, limit: float, spent: float) -> None:
23
+ super().__init__(f"budget for resource {resource!r} of {limit} exhausted: spent {spent}")
24
+ self.resource = resource
25
+ self.limit = limit
26
+ self.spent = spent
15
27
 
16
28
 
17
29
  class BudgetReentryError(RuntimeError):
@@ -100,9 +112,7 @@ class Budget:
100
112
  "resource=%s limit=%s exhausted: spent=%s", key, limit.amount, spent
101
113
  )
102
114
  else:
103
- raise BudgetExhaustedError(
104
- f"budget for resource {key!r} of {limit.amount} exhausted: spent {spent}"
105
- )
115
+ raise BudgetExhaustedError(key, limit.amount, spent)
106
116
 
107
117
  def __enter__(self) -> "Budget":
108
118
  with self._lock: