policyengine 3.1.8__py3-none-any.whl → 3.1.10__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.
- policyengine/__pycache__/__init__.cpython-313.pyc +0 -0
- policyengine/core/cache.py +56 -0
- policyengine/core/simulation.py +8 -0
- {policyengine-3.1.8.dist-info → policyengine-3.1.10.dist-info}/METADATA +2 -1
- {policyengine-3.1.8.dist-info → policyengine-3.1.10.dist-info}/RECORD +8 -7
- {policyengine-3.1.8.dist-info → policyengine-3.1.10.dist-info}/WHEEL +0 -0
- {policyengine-3.1.8.dist-info → policyengine-3.1.10.dist-info}/licenses/LICENSE +0 -0
- {policyengine-3.1.8.dist-info → policyengine-3.1.10.dist-info}/top_level.txt +0 -0
|
Binary file
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from collections import OrderedDict
|
|
3
|
+
|
|
4
|
+
import psutil
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
_MEMORY_THRESHOLDS_GB = [8, 16, 32]
|
|
9
|
+
_warned_thresholds: set[int] = set()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LRUCache[T]:
|
|
13
|
+
"""Least-recently-used cache with configurable size limit and memory monitoring."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, max_size: int = 100):
|
|
16
|
+
self._max_size = max_size
|
|
17
|
+
self._cache: OrderedDict[str, T] = OrderedDict()
|
|
18
|
+
|
|
19
|
+
def get(self, key: str) -> T | None:
|
|
20
|
+
"""Get item from cache, marking it as recently used."""
|
|
21
|
+
if key not in self._cache:
|
|
22
|
+
return None
|
|
23
|
+
self._cache.move_to_end(key)
|
|
24
|
+
return self._cache[key]
|
|
25
|
+
|
|
26
|
+
def add(self, key: str, value: T) -> None:
|
|
27
|
+
"""Add item to cache with LRU eviction when full."""
|
|
28
|
+
if key in self._cache:
|
|
29
|
+
self._cache.move_to_end(key)
|
|
30
|
+
else:
|
|
31
|
+
self._cache[key] = value
|
|
32
|
+
if len(self._cache) > self._max_size:
|
|
33
|
+
self._cache.popitem(last=False)
|
|
34
|
+
|
|
35
|
+
self._check_memory_usage()
|
|
36
|
+
|
|
37
|
+
def clear(self) -> None:
|
|
38
|
+
"""Clear all items from cache."""
|
|
39
|
+
self._cache.clear()
|
|
40
|
+
_warned_thresholds.clear()
|
|
41
|
+
|
|
42
|
+
def __len__(self) -> int:
|
|
43
|
+
return len(self._cache)
|
|
44
|
+
|
|
45
|
+
def _check_memory_usage(self) -> None:
|
|
46
|
+
"""Check memory usage and warn at threshold crossings."""
|
|
47
|
+
process = psutil.Process()
|
|
48
|
+
memory_gb = process.memory_info().rss / (1024**3)
|
|
49
|
+
|
|
50
|
+
for threshold in _MEMORY_THRESHOLDS_GB:
|
|
51
|
+
if memory_gb >= threshold and threshold not in _warned_thresholds:
|
|
52
|
+
logger.warning(
|
|
53
|
+
f"Memory usage has reached {memory_gb:.2f}GB (threshold: {threshold}GB). "
|
|
54
|
+
f"Cache contains {len(self._cache)} items."
|
|
55
|
+
)
|
|
56
|
+
_warned_thresholds.add(threshold)
|
policyengine/core/simulation.py
CHANGED
|
@@ -3,11 +3,14 @@ from uuid import uuid4
|
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
6
|
+
from .cache import LRUCache
|
|
6
7
|
from .dataset import Dataset
|
|
7
8
|
from .dynamic import Dynamic
|
|
8
9
|
from .policy import Policy
|
|
9
10
|
from .tax_benefit_model_version import TaxBenefitModelVersion
|
|
10
11
|
|
|
12
|
+
_cache: LRUCache["Simulation"] = LRUCache(max_size=100)
|
|
13
|
+
|
|
11
14
|
|
|
12
15
|
class Simulation(BaseModel):
|
|
13
16
|
id: str = Field(default_factory=lambda: str(uuid4()))
|
|
@@ -25,12 +28,17 @@ class Simulation(BaseModel):
|
|
|
25
28
|
self.tax_benefit_model_version.run(self)
|
|
26
29
|
|
|
27
30
|
def ensure(self):
|
|
31
|
+
cached_result = _cache.get(self.id)
|
|
32
|
+
if cached_result:
|
|
33
|
+
self.output_dataset = cached_result.output_dataset
|
|
28
34
|
try:
|
|
29
35
|
self.tax_benefit_model_version.load(self)
|
|
30
36
|
except Exception:
|
|
31
37
|
self.run()
|
|
32
38
|
self.save()
|
|
33
39
|
|
|
40
|
+
_cache.add(self.id, self)
|
|
41
|
+
|
|
34
42
|
def save(self):
|
|
35
43
|
"""Save the simulation's output dataset."""
|
|
36
44
|
self.tax_benefit_model_version.save(self)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: policyengine
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.10
|
|
4
4
|
Summary: A package to conduct policy analysis using PolicyEngine tax-benefit models.
|
|
5
5
|
Author-email: PolicyEngine <hello@policyengine.org>
|
|
6
6
|
License: GNU AFFERO GENERAL PUBLIC LICENSE
|
|
@@ -673,6 +673,7 @@ Requires-Dist: pandas>=2.0.0
|
|
|
673
673
|
Requires-Dist: microdf_python
|
|
674
674
|
Requires-Dist: plotly>=5.0.0
|
|
675
675
|
Requires-Dist: requests>=2.31.0
|
|
676
|
+
Requires-Dist: psutil>=5.9.0
|
|
676
677
|
Provides-Extra: uk
|
|
677
678
|
Requires-Dist: policyengine_core>=3.10; extra == "uk"
|
|
678
679
|
Requires-Dist: policyengine-uk>=2.51.0; extra == "uk"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
policyengine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
policyengine/__pycache__/__init__.cpython-313.pyc,sha256=
|
|
2
|
+
policyengine/__pycache__/__init__.cpython-313.pyc,sha256=mZImDZy8jD5TfkzSGmnvTewIqi_PKHPX-jgLJt_VND4,175
|
|
3
3
|
policyengine/core/__init__.py,sha256=KBVhkqzkvjWLDDwk96vquQKL63ZFuLen5AzBOBnO9pg,912
|
|
4
|
+
policyengine/core/cache.py,sha256=DcVVFaCt7k9PmqwlhXoNDMtJ8sF4neYP1uRqWik5QYg,1812
|
|
4
5
|
policyengine/core/dataset.py,sha256=iJr9-J6w11uMRYy3EEJO9Gveku1m71AA1yzeo-0SiCs,16094
|
|
5
6
|
policyengine/core/dataset_version.py,sha256=6KeFCRGQto_Yyl4QY4Vo2JFythjaXrNAOHQiwRGESyM,378
|
|
6
7
|
policyengine/core/dynamic.py,sha256=ng9BjDzxdwjJ0e7zoqXFmq33E1SRbaaPYfW7pjRSSzI,1641
|
|
@@ -8,7 +9,7 @@ policyengine/core/output.py,sha256=cCW4vbzkLdQaT_nJTyDJBl7Hubm7nZeRuR7aVG1dKvg,6
|
|
|
8
9
|
policyengine/core/parameter.py,sha256=8RKKuGCDW1OoHPoXI9vF3JY6COc1qhUtMolXTUxPoEs,626
|
|
9
10
|
policyengine/core/parameter_value.py,sha256=ZRBZWFYtaY9TqdgjrCymzOZNmuKOBZsrWBET24DIJ_Q,434
|
|
10
11
|
policyengine/core/policy.py,sha256=ExMrUDMvNk_uuOL0cSm0UCzDyGka0t_yk6x4U0Kp6Ww,1635
|
|
11
|
-
policyengine/core/simulation.py,sha256=
|
|
12
|
+
policyengine/core/simulation.py,sha256=QL9nbQNjNDaWPRoiIWotrBcN0RlRSZ0sDcWAB5yX47o,1387
|
|
12
13
|
policyengine/core/tax_benefit_model.py,sha256=2Yc1RlQrUG7djDMZbJOQH4Ns86_lOnLeISCGR4-9zMo,176
|
|
13
14
|
policyengine/core/tax_benefit_model_version.py,sha256=V1CGft5Y6YflMASx0wR3V73jr-WqQu2R8N5QVMRm9yw,2752
|
|
14
15
|
policyengine/core/variable.py,sha256=AjSImORlRkh05xhYxyeT6GFMOfViRzYg0qRQAIj-mxo,350
|
|
@@ -32,8 +33,8 @@ policyengine/utils/__init__.py,sha256=1X-VYAWLyB9A0YRHwsGWrqQHns1WfeZ7ISC6DMU5my
|
|
|
32
33
|
policyengine/utils/dates.py,sha256=HnAqyl8S8EOYp8ibsnMTmECYoDWCSqwL-7A2_qKgxSc,1510
|
|
33
34
|
policyengine/utils/parametric_reforms.py,sha256=4P3U39-4pYTU4BN6JjgmVLUkCkBhRfZJ6UIWTlsjyQE,1155
|
|
34
35
|
policyengine/utils/plotting.py,sha256=ZAzTWz38vIaW0c3Nt4Un1kfrNoXLyHCDd1pEJIlsRg4,5335
|
|
35
|
-
policyengine-3.1.
|
|
36
|
-
policyengine-3.1.
|
|
37
|
-
policyengine-3.1.
|
|
38
|
-
policyengine-3.1.
|
|
39
|
-
policyengine-3.1.
|
|
36
|
+
policyengine-3.1.10.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
37
|
+
policyengine-3.1.10.dist-info/METADATA,sha256=aTgds3H8GrpG_5XFbD1Ftjgnyv5WfdVYAtvXVJA_BW8,45919
|
|
38
|
+
policyengine-3.1.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
39
|
+
policyengine-3.1.10.dist-info/top_level.txt,sha256=_23UPobfkneHQkpJ0e0OmDJfhCUfoXj_F2sTckCGOH4,13
|
|
40
|
+
policyengine-3.1.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|