Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitca1a72b

Browse files
BadSingletonlostmsu
authored andcommitted
Add tests for exception leaking.
Originally from PR#1402. The underlying bug is now fixed, but the testsare atill applicable.
1 parentb7fb03a commitca1a72b

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

‎src/testing/exceptiontest.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
usingPython.Runtime;
12
usingSystem;
23
usingSystem.Collections;
34
usingSystem.Collections.Generic;
@@ -81,6 +82,40 @@ public static void ThrowChainedExceptions()
8182
thrownewException("Outer exception",exc2);
8283
}
8384
}
85+
86+
publicstaticIntPtrDoThrowSimple()
87+
{
88+
using(Py.GIL())
89+
{
90+
dynamicbuiltins=Py.Import("builtins");
91+
vartypeErrorType=newPyType(builtins.TypeError);
92+
varpyerr=newPythonException(typeErrorType,value:null,traceback:null,"Type error, the first",innerException:null);
93+
thrownewArgumentException("Bogus bad parameter",pyerr);
94+
95+
}
96+
}
97+
98+
publicstaticvoidDoThrowWithInner()
99+
{
100+
using(Py.GIL())
101+
{
102+
// create a TypeError
103+
dynamicbuiltins=Py.Import("builtins");
104+
varpyerrFirst=newPythonException(newPyType(builtins.TypeError),value:null,traceback:null,"Type error, the first",innerException:null);
105+
106+
// Create an ArgumentException, but as a python exception, with the previous type error as the inner exception
107+
varargExc=newArgumentException("Bogus bad parameter",pyerrFirst);
108+
varargExcPyObj=argExc.ToPython();
109+
varpyArgExc=newPythonException(argExcPyObj.GetPythonType(),value:null,traceback:null,argExc.Message,innerException:argExc.InnerException);
110+
// This object must be disposed explicitly or else we get a false-positive leak.
111+
argExcPyObj.Dispose();
112+
113+
// Then throw a TypeError with the ArgumentException-as-python-error exception as inner.
114+
varpyerrSecond=newPythonException(newPyType(builtins.TypeError),value:null,traceback:null,"Type error, the second",innerException:pyArgExc);
115+
throwpyerrSecond;
116+
117+
}
118+
}
84119
}
85120

86121

‎tests/test_exceptions.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,51 @@
88
importpytest
99
importpickle
1010

11+
# begin code from https://utcc.utoronto.ca/~cks/space/blog/python/GetAllObjects
12+
importgc
13+
# Recursively expand slist's objects
14+
# into olist, using seen to track
15+
# already processed objects.
16+
17+
def_getr(slist,olist,seen):
18+
foreinslist:
19+
ifid(e)inseen:
20+
continue
21+
seen[id(e)]=None
22+
olist.append(e)
23+
tl=gc.get_referents(e)
24+
iftl:
25+
_getr(tl,olist,seen)
26+
27+
# The public function.
28+
defget_all_objects():
29+
gcl=gc.get_objects()
30+
olist= []
31+
seen= {}
32+
# Just in case:
33+
seen[id(gcl)]=None
34+
seen[id(olist)]=None
35+
seen[id(seen)]=None
36+
# _getr does the real work.
37+
_getr(gcl,olist,seen)
38+
returnolist
39+
# end code from https://utcc.utoronto.ca/~cks/space/blog/python/GetAllObjects
40+
41+
defleak_check(func):
42+
defdo_leak_check():
43+
func()
44+
gc.collect()
45+
exc= {xforxinget_all_objects()ifisinstance(x,Exception)andnotisinstance(x,pytest.PytestDeprecationWarning)}
46+
print(len(exc))
47+
iflen(exc):
48+
forxinexc:
49+
print('-------')
50+
print(repr(x))
51+
print(gc.get_referrers(x))
52+
print(len(gc.get_referrers(x)))
53+
assertFalse
54+
gc.collect()
55+
returndo_leak_check
1156

1257
deftest_unified_exception_semantics():
1358
"""Test unified exception semantics."""
@@ -375,3 +420,33 @@ def test_iteration_innerexception():
375420
# after exception is thrown iterator is no longer valid
376421
withpytest.raises(StopIteration):
377422
next(val)
423+
424+
defleak_test(func):
425+
defdo_test_leak():
426+
# PyTest leaks things, gather the current state
427+
orig_exc= {xforxinget_all_objects()ifisinstance(x,Exception)}
428+
func()
429+
exc= {xforxinget_all_objects()ifisinstance(x,Exception)}
430+
possibly_leaked=exc-orig_exc
431+
assertnotpossibly_leaked
432+
433+
returndo_test_leak
434+
435+
@leak_test
436+
deftest_dont_leak_exceptions_simple():
437+
fromPython.TestimportExceptionTest
438+
439+
try:
440+
ExceptionTest.DoThrowSimple()
441+
exceptSystem.ArgumentException:
442+
print('type error, as expected')
443+
444+
@leak_test
445+
deftest_dont_leak_exceptions_inner():
446+
fromPython.TestimportExceptionTest
447+
try:
448+
ExceptionTest.DoThrowWithInner()
449+
exceptTypeError:
450+
print('type error, as expected')
451+
exceptSystem.ArgumentException:
452+
print('type error, also expected')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp