Skip to content

Commit 22c7d92

Browse files
committed
trim ram in multidict_pop.py when testing item deletion so that bougus claims can be prevented. add types-psutil to pre-commit for typechecking the test
2 parents c06df7d + 8acea81 commit 22c7d92

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ repos:
130130
- pytest_codspeed
131131
- Sphinx >= 5.3.0
132132
- sphinxcontrib-spelling
133+
- types-psutil
134+
- psutil
133135
args:
134136
- --python-version=3.13
135137
- --txt-report=.tox/.tmp/.mypy/python-3.13
@@ -146,6 +148,8 @@ repos:
146148
- pytest_codspeed
147149
- Sphinx >= 5.3.0
148150
- sphinxcontrib-spelling
151+
- types-psutil
152+
- psutil
149153
args:
150154
- --python-version=3.11
151155
- --txt-report=.tox/.tmp/.mypy/python-3.11

requirements/pytest.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ objgraph==3.6.2
22
pytest==8.4.0
33
pytest-codspeed==3.2.0
44
pytest-cov==6.1.0
5-
psutil==7.0.0
5+
psutil==7.0.0

tests/isolated/multidict_pop.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
# Test for memory leaks surrounding deletion of values.
2-
# SEE: https://github.com/aio-libs/multidict/issues/1232
3-
# We want to make sure that bad predictions or bougus claims
4-
# can be prevented in the future.
2+
# SEE: https://github.com/aio-libs/multidict/issues/1232
3+
# We want to make sure that bad predictions or bougus claims
4+
# of memory leaks can be prevented in the future.
55

66
import gc
77
import sys
88
import psutil
99
import os
1010
import ctypes
1111
from multidict import MultiDict
12+
from typing import Optional
1213

13-
# Code was borrowed for testing with windows
14+
15+
# Code was borrowed for testing with windows and other operating systems respectively.
1416
# SEE: https://stackoverflow.com/a/79150440
1517

16-
def trim_windows_process_memory(pid: int = None) -> bool:
18+
19+
def trim_windows_process_memory(pid: Optional[int] = None) -> bool:
1720
"""Causes effect similar to malloc_trim on -nix."""
1821

1922
SIZE_T = ctypes.c_uint32 if ctypes.sizeof(ctypes.c_void_p) == 4 else ctypes.c_uint64
@@ -22,9 +25,9 @@ def trim_windows_process_memory(pid: int = None) -> bool:
2225
if not pid:
2326
pid = ctypes.windll.kernel32.GetCurrentProcess()
2427

25-
# Sometimes FileNotFoundError can appear so the code was
28+
# Sometimes FileNotFoundError can appear so the code was
2629
# changed to handle that workaround.
27-
30+
2831
ctypes.windll.kernel32.SetProcessWorkingSetSizeEx.argtypes = [
2932
ctypes.c_void_p, # Process handle
3033
SIZE_T, # Minimum working set size
@@ -37,14 +40,15 @@ def trim_windows_process_memory(pid: int = None) -> bool:
3740
QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002
3841

3942
# Attempt to set the working set size
40-
if not ctypes.windll.kernel32.SetProcessWorkingSetSizeEx(pid, SIZE_T(-1), SIZE_T(-1), QUOTA_LIMITS_HARDWS_MIN_DISABLE):
43+
if not ctypes.windll.kernel32.SetProcessWorkingSetSizeEx(
44+
pid, SIZE_T(-1), SIZE_T(-1), QUOTA_LIMITS_HARDWS_MIN_DISABLE
45+
):
4146
# Retrieve the error code
4247
error_code = ctypes.windll.kernel32.GetLastError()
4348
# let's print it since we aren't using a logger...
4449
print(f"SetProcessWorkingSetSizeEx failed with error code: {error_code}")
4550
return False
4651
return True
47-
4852

4953

5054
def trim_ram() -> None:
@@ -60,63 +64,69 @@ def trim_ram() -> None:
6064
except Exception as e:
6165
print(" attempt failed")
6266
raise e
63-
64-
def get_memory_usage():
67+
68+
69+
def get_memory_usage() -> int:
6570
process = psutil.Process(os.getpid())
6671
memory_info = process.memory_info()
67-
return memory_info.rss / (1024 * 1024)
72+
return memory_info.rss / (1024 * 1024) # type: ignore[no-any-return]
73+
6874

6975
keys = [f"X-Any-{i}" for i in range(1000)]
7076
headers = {key: key * 2 for key in keys}
7177

7278

73-
def check_for_leak():
79+
def check_for_leak() -> None:
7480
trim_ram()
7581
usage = get_memory_usage()
7682
# We should never go over 100MB
7783
if usage > 100:
7884
sys.exit(1)
7985

8086

81-
def _test_pop():
87+
def _test_pop() -> None:
8288
for _ in range(10):
8389
for _ in range(1000):
8490
result = MultiDict(headers)
8591
for k in keys:
8692
result.pop(k)
8793
check_for_leak()
8894

89-
def _test_popall():
95+
96+
def _test_popall() -> None:
9097
for _ in range(10):
9198
for _ in range(1000):
9299
result = MultiDict(headers)
93100
for k in keys:
94101
result.popall(k)
95102
check_for_leak()
96103

97-
def _test_popone():
104+
105+
def _test_popone() -> None:
98106
for _ in range(10):
99107
for _ in range(1000):
100108
result = MultiDict(headers)
101109
for k in keys:
102110
result.popone(k)
103111
check_for_leak()
104112

105-
def _test_del():
113+
114+
def _test_del() -> None:
106115
for _ in range(10):
107116
for _ in range(1000):
108117
result = MultiDict(headers)
109118
for k in keys:
110119
del result[k]
111120
check_for_leak()
112121

122+
113123
def _run_isolated_case() -> None:
114124
_test_pop()
115125
_test_popall()
116126
_test_popone()
117127
_test_del()
118128
sys.exit(0)
119129

130+
120131
if __name__ == "__main__":
121132
_run_isolated_case()
122-

tests/test_leaks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"multidict_extend_multidict.py",
1616
"multidict_extend_tuple.py",
1717
"multidict_update_multidict.py",
18-
"multidict_pop.py"
18+
"multidict_pop.py",
1919
),
2020
)
2121
@pytest.mark.leaks

0 commit comments

Comments
 (0)