Skip to content

Commit 4327f17

Browse files
authored
Merge branch 'main' into zmq_anyio
2 parents 255cd27 + b3a0999 commit 4327f17

File tree

4 files changed

+99
-18
lines changed

4 files changed

+99
-18
lines changed

pyproject.toml

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,62 @@ build = [
132132
[tool.mypy]
133133
files = "ipykernel"
134134
strict = true
135+
#disable_error_code = [ "import-not-found"]
135136
disable_error_code = ["no-untyped-def", "no-untyped-call", "import-not-found"]
136137
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
137138
follow_imports = "normal"
138-
pretty = true
139+
#pretty = true
139140
warn_unreachable = true
140141

142+
[[tool.mypy.overrides]]
143+
module = [
144+
"ipykernel._eventloop_macos",
145+
"ipykernel.comm.comm",
146+
"ipykernel.comm.manager",
147+
"ipykernel.compiler",
148+
"ipykernel.connect",
149+
"ipykernel.control",
150+
"ipykernel.datapub",
151+
"ipykernel.debugger",
152+
"ipykernel.displayhook",
153+
"ipykernel.embed",
154+
"ipykernel.eventloops",
155+
"ipykernel.gui.gtk3embed",
156+
"ipykernel.gui.gtkembed",
157+
"ipykernel.heartbeat",
158+
"ipykernel.inprocess.blocking",
159+
"ipykernel.inprocess.channels",
160+
"ipykernel.inprocess.client",
161+
"ipykernel.inprocess.ipkernel",
162+
"ipykernel.inprocess.manager",
163+
"ipykernel.inprocess.session",
164+
"ipykernel.inprocess.socket",
165+
"ipykernel.iostream",
166+
"ipykernel.ipkernel",
167+
"ipykernel.jsonutil",
168+
"ipykernel.kernelapp",
169+
"ipykernel.kernelbase",
170+
"ipykernel.log",
171+
"ipykernel.parentpoller",
172+
"ipykernel.pickleutil",
173+
"ipykernel.serialize",
174+
"ipykernel.shellchannel",
175+
"ipykernel.subshell",
176+
"ipykernel.subshell_manager",
177+
"ipykernel.thread",
178+
"ipykernel.trio_runner",
179+
"ipykernel.zmqshell"
180+
]
181+
#check_untyped_defs = false
182+
#disallow_incomplete_defs = false
183+
#disallow_untyped_calls = false
184+
#disallow_untyped_decorators = false
185+
#disallow_untyped_defs = false
186+
#ignore_missing_imports = true
187+
#follow_untyped_imports = false
188+
189+
190+
141191
[tool.pytest.ini_options]
142192
minversion = "6.0"
143193
xfail_strict = true
@@ -174,6 +224,10 @@ filterwarnings= [
174224
# Ignore jupyter_client warnings
175225
"module:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning",
176226

227+
# we do not want to raise on resources warnings, or we will not have a chance to
228+
# collect the messages and print the location of the leak
229+
"always::ResourceWarning",
230+
177231
# ignore unclosed sqlite in traits
178232
"ignore:unclosed database in <sqlite3.Connection:ResourceWarning",
179233

tests/conftest.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import logging
2+
import os
3+
import warnings
24
from math import inf
35
from threading import Event
46
from typing import Any, Callable, no_type_check
@@ -21,6 +23,11 @@
2123
# Windows
2224
resource = None # type:ignore
2325

26+
try:
27+
import tracemalloc
28+
except ModuleNotFoundError:
29+
tracemalloc = None
30+
2431

2532
pytestmark = pytest.mark.anyio
2633

@@ -200,3 +207,38 @@ async def ipkernel(anyio_backend):
200207
yield kernel
201208
kernel.destroy()
202209
ZMQInteractiveShell.clear_instance()
210+
211+
212+
@pytest.fixture()
213+
def tracemalloc_resource_warning(recwarn, N=10):
214+
"""fixture to enable tracemalloc for a single test, and report the
215+
location of the leaked resource
216+
217+
We cannot only enable tracemalloc, as otherwise it is stopped just after the
218+
test, the frame cache is cleared by tracemalloc.stop() and thus the warning
219+
printing code get None when doing
220+
`tracemalloc.get_object_traceback(r.source)`.
221+
222+
So we need to both filter the warnings to enable ResourceWarning, and loop
223+
through it print the stack before we stop tracemalloc and continue.
224+
225+
"""
226+
if tracemalloc is None:
227+
yield
228+
return
229+
230+
tracemalloc.start(N)
231+
with warnings.catch_warnings():
232+
warnings.simplefilter("always", category=ResourceWarning)
233+
yield None
234+
try:
235+
for r in recwarn:
236+
if r.category is ResourceWarning and r.source is not None:
237+
tb = tracemalloc.get_object_traceback(r.source)
238+
if tb:
239+
info = f"Leaking resource:{r}\n |" + "\n |".join(tb.format())
240+
# technically an Error and not a failure as we fail in the fixture
241+
# and not the test
242+
pytest.fail(info)
243+
finally:
244+
tracemalloc.stop()

tests/test_connect.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,6 @@
1919

2020
from .utils import TemporaryWorkingDirectory
2121

22-
23-
@pytest.fixture(scope="module", autouse=True)
24-
def _enable_tracemalloc():
25-
try:
26-
import tracemalloc
27-
except ModuleNotFoundError:
28-
# pypy
29-
tracemalloc = None
30-
if tracemalloc is not None:
31-
tracemalloc.start()
32-
yield
33-
if tracemalloc is not None:
34-
tracemalloc.stop()
35-
36-
3722
sample_info: dict = {
3823
"ip": "1.2.3.4",
3924
"transport": "ipc",
@@ -133,7 +118,7 @@ def test_port_bind_failure_recovery(request):
133118
app.init_sockets()
134119

135120

136-
def test_port_bind_failure_gives_up_retries(request):
121+
def test_port_bind_failure_gives_up_retries(request, tracemalloc_resource_warning):
137122
cfg = Config()
138123
with TemporaryWorkingDirectory() as d:
139124
cfg.ProfileDir.location = d

tests/test_ipkernel_direct.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ async def test_direct_execute_request_aborting(ipkernel):
5151
assert reply["content"]["status"] == "aborted"
5252

5353

54-
async def test_complete_request(ipkernel):
54+
async def test_complete_request(ipkernel, tracemalloc_resource_warning):
5555
reply = await ipkernel.test_shell_message("complete_request", dict(code="hello", cursor_pos=0))
5656
assert reply["header"]["msg_type"] == "complete_reply"
5757
ipkernel.use_experimental_completions = False

0 commit comments

Comments
 (0)