Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
c9952ac5
Commit
c9952ac5
authored
Jun 25, 2015
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix the leak checks by clearing the tracebacks at certain points in the tests.
parent
e00862dd
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
41 additions
and
2 deletions
+41
-2
changelog.rst
changelog.rst
+4
-0
gevent/greenlet.py
gevent/greenlet.py
+17
-1
gevent/pool.py
gevent/pool.py
+4
-0
greentest/greentest.py
greentest/greentest.py
+2
-1
greentest/test__event.py
greentest/test__event.py
+1
-0
greentest/test__exc_info.py
greentest/test__exc_info.py
+1
-0
greentest/test__greenlet.py
greentest/test__greenlet.py
+7
-0
greentest/test__server.py
greentest/test__server.py
+3
-0
greentest/test__socket_close.py
greentest/test__socket_close.py
+1
-0
greentest/test__systemerror.py
greentest/test__systemerror.py
+1
-0
No files found.
changelog.rst
View file @
c9952ac5
...
...
@@ -24,6 +24,10 @@ Unreleased
- ``gevent.queue.JoinableQueue`` treats ``items`` passed to
``__init__`` as unfinished tasks, the same as if they were ``put``.
Initial PR #554 by DuLLSoN.
- (Experimental.) Waiting on or getting results from greenlets that
raised exceptions now usually raises the original traceback. This
should assist things like Sentry to track the original problem. PRs
#450 and #528 by Rodolfo and Eddi Linder.
Release 1.0.2
-------------
...
...
gevent/greenlet.py
View file @
c9952ac5
...
...
@@ -122,6 +122,14 @@ class Greenlet(greenlet):
def
_raise_exception
(
self
):
reraise
(
*
self
.
_exc_info
)
def
_exc_clear
(
self
):
"""Throw away the traceback associated with the exception on this object.
Call this to resolve any reference cycles.
"""
if
self
.
_exc_info
:
self
.
_exc_info
=
(
self
.
_exc_info
[
0
],
self
.
_exc_info
[
1
],
None
)
@
property
def
loop
(
self
):
# needed by killall
...
...
@@ -437,11 +445,19 @@ def _kill(greenlet, exception, waiter):
def
joinall
(
greenlets
,
timeout
=
None
,
raise_error
=
False
,
count
=
None
):
if
not
raise_error
:
wait
(
greenlets
,
timeout
=
timeout
,
count
=
count
)
for
g
in
greenlets
:
if
hasattr
(
g
,
'_exc_clear'
):
g
.
_exc_clear
()
else
:
for
obj
in
iwait
(
greenlets
,
timeout
=
timeout
,
count
=
count
):
if
getattr
(
obj
,
'exception'
,
None
)
is
not
None
:
if
hasattr
(
obj
,
'_raise_exception'
):
obj
.
_raise_exception
()
try
:
obj
.
_raise_exception
()
finally
:
for
g
in
greenlets
:
if
hasattr
(
g
,
'_exc_clear'
):
g
.
_exc_clear
()
else
:
raise
obj
.
exception
...
...
gevent/pool.py
View file @
c9952ac5
...
...
@@ -241,6 +241,7 @@ class IMapUnordered(Greenlet):
self
.
queue
.
put
(
greenlet
.
value
)
else
:
self
.
queue
.
put
(
Failure
(
greenlet
.
exception
))
greenlet
.
_exc_clear
()
if
self
.
ready
()
and
self
.
count
<=
0
and
not
self
.
finished
:
self
.
queue
.
put
(
Failure
(
StopIteration
))
self
.
finished
=
True
...
...
@@ -250,6 +251,7 @@ class IMapUnordered(Greenlet):
return
if
not
self
.
successful
():
self
.
queue
.
put
(
Failure
(
self
.
exception
))
self
.
_exc_clear
()
self
.
finished
=
True
return
if
self
.
count
<=
0
:
...
...
@@ -315,6 +317,7 @@ class IMap(Greenlet):
self
.
queue
.
put
((
greenlet
.
index
,
greenlet
.
value
))
else
:
self
.
queue
.
put
((
greenlet
.
index
,
Failure
(
greenlet
.
exception
)))
greenlet
.
_exc_clear
()
if
self
.
ready
()
and
self
.
count
<=
0
and
not
self
.
finished
:
self
.
maxindex
+=
1
self
.
queue
.
put
((
self
.
maxindex
,
Failure
(
StopIteration
)))
...
...
@@ -326,6 +329,7 @@ class IMap(Greenlet):
if
not
self
.
successful
():
self
.
maxindex
+=
1
self
.
queue
.
put
((
self
.
maxindex
,
Failure
(
self
.
exception
)))
self
.
_exc_clear
()
self
.
finished
=
True
return
if
self
.
count
<=
0
:
...
...
greentest/greentest.py
View file @
c9952ac5
...
...
@@ -21,6 +21,7 @@
# package is named greentest, not test, so it won't be confused with test in stdlib
import
sys
import
types
import
unittest
from
unittest
import
TestCase
as
BaseTestCase
import
time
...
...
@@ -89,7 +90,7 @@ def wrap_refcount(method):
return
method
# Some builtin things that we ignore
IGNORED_TYPES
=
(
tuple
,
dict
)
IGNORED_TYPES
=
(
tuple
,
dict
,
types
.
FrameType
)
def
type_hist
():
import
collections
...
...
greentest/test__event.py
View file @
c9952ac5
...
...
@@ -96,6 +96,7 @@ class TestAsyncResultAsLinkTarget(greentest.TestCase):
self
.
assertRaises
(
greentest
.
ExpectedException
,
s1
.
get
)
assert
gevent
.
with_timeout
(
DELAY
,
s2
.
get
,
timeout_value
=
X
)
is
X
self
.
assertRaises
(
greentest
.
ExpectedException
,
s3
.
get
)
g
.
_exc_clear
()
class
TestEvent_SetThenClear
(
greentest
.
TestCase
):
...
...
greentest/test__exc_info.py
View file @
c9952ac5
...
...
@@ -46,6 +46,7 @@ class Test(greentest.TestCase):
except
Exception
:
ex
=
sys
.
exc_info
()[
1
]
assert
ex
is
error
,
(
ex
,
error
)
g
.
_exc_clear
()
def
test2
(
self
):
timer
=
gevent
.
get_hub
().
loop
.
timer
(
0
)
...
...
greentest/test__greenlet.py
View file @
c9952ac5
...
...
@@ -67,6 +67,7 @@ class TestLink(greentest.TestCase):
event
=
AsyncResult
()
p
.
link
(
event
)
self
.
assertRaises
(
err
,
event
.
get
)
p
.
_exc_clear
()
for
i
in
range
(
3
):
event2
=
AsyncResult
()
...
...
@@ -238,6 +239,7 @@ class TestRaise_link(LinksTestCase):
assert
not
callback_flag
,
callback_flag
self
.
check_timed_out
(
*
xxxxx
)
p
.
_exc_clear
()
def
test_raise
(
self
):
p
=
self
.
p
=
gevent
.
spawn
(
lambda
:
getcurrent
().
throw
(
ExpectedError
(
'test_raise'
)))
...
...
@@ -275,6 +277,8 @@ class TestStuff(greentest.TestCase):
self
.
assertRaises
(
ExpectedError
,
gevent
.
joinall
,
[
x
,
y
],
raise_error
=
True
)
self
.
assertRaises
(
ExpectedError
,
gevent
.
joinall
,
[
y
],
raise_error
=
True
)
x
.
join
()
x
.
_exc_clear
()
y
.
_exc_clear
()
def
test_joinall_exception_order
(
self
):
# if there're several exceptions raised, the earliest one must be raised by joinall
...
...
@@ -342,6 +346,7 @@ class TestStuff(greentest.TestCase):
p
.
link
(
listener3
)
sleep
(
DELAY
*
10
)
assert
results
in
[[
10
,
20
],
[
20
,
10
]],
results
p
.
_exc_clear
()
class
Results
(
object
):
...
...
@@ -541,6 +546,7 @@ class TestBasic(greentest.TestCase):
assert
g
.
value
is
None
# not changed
assert
g
.
exception
.
myattr
==
5
assert
link_test
==
[
g
],
link_test
g
.
_exc_clear
()
def
_assertKilled
(
self
,
g
):
assert
not
g
...
...
@@ -550,6 +556,7 @@ class TestBasic(greentest.TestCase):
assert
g
.
successful
(),
(
repr
(
g
),
g
.
value
,
g
.
exception
)
assert
isinstance
(
g
.
value
,
gevent
.
GreenletExit
),
(
repr
(
g
),
g
.
value
,
g
.
exception
)
assert
g
.
exception
is
None
g
.
_exc_clear
()
def
assertKilled
(
self
,
g
):
self
.
_assertKilled
(
g
)
...
...
greentest/test__server.py
View file @
c9952ac5
...
...
@@ -181,6 +181,9 @@ class TestCase(greentest.TestCase):
self
.
assert_error
(
TypeError
)
finally
:
self
.
server
.
stop
()
# XXX: There's an unreachable greenlet that has a traceback.
# We need to clear it to make the leak checks work
import
gc
;
gc
.
collect
()
def
ServerClass
(
self
,
*
args
,
**
kwargs
):
kwargs
.
setdefault
(
'spawn'
,
self
.
get_spawn
())
...
...
greentest/test__socket_close.py
View file @
c9952ac5
...
...
@@ -36,6 +36,7 @@ class Test(greentest.TestCase):
self
.
assertEqual
(
receiver
.
exception
.
errno
,
socket
.
EBADF
)
finally
:
receiver
.
kill
()
receiver
.
_exc_clear
()
def
test_recv_twice
(
self
):
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
...
...
greentest/test__systemerror.py
View file @
c9952ac5
...
...
@@ -64,6 +64,7 @@ class TestSpawn(Test):
def
tearDown
(
self
):
gevent
.
sleep
(
0.0001
)
assert
self
.
x
.
dead
,
self
.
x
self
.
x
.
_exc_clear
()
def
start
(
self
,
*
args
):
self
.
x
=
gevent
.
spawn
(
*
args
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment