Skip to content

Commit

Permalink
defer: Move basic inlineCallbacks tests to test_inlinecb
Browse files Browse the repository at this point in the history
deferredGenerator and inlineCallbacks tests just happen to be similar
enough that some of them can be shared. However, this sharing is
ephemeral because there's no underlying reason why both sets of tests
should change both at the same time. Changes to how inlineCallbacks
works will affect only that part of the test suite and changes to how
deferredGenerator will affect only its part of the test suite as well.

Duplicating the tests makes them easier to discover and understand.
Additionally, this will need to be done at some point anyway because
deferredGenerator has been deprecated.
  • Loading branch information
p12tic committed May 6, 2024
1 parent 5ca1828 commit 1debeec
Show file tree
Hide file tree
Showing 2 changed files with 301 additions and 271 deletions.
247 changes: 247 additions & 0 deletions src/twisted/internet/test/test_inlinecb.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,253 @@
from twisted.trial.unittest import SynchronousTestCase, TestCase


class BasicTests(TestCase):
# First provide all the generator impls necessary for BaseDefgenTests

@inlineCallbacks
def _genBasics(self):
x = yield getThing()

self.assertEqual(x, "hi")

Check warning on line 29 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L29

Added line #L29 was not covered by tests

try:
yield getOwie()
except ZeroDivisionError as e:
self.assertEqual(str(e), "OMG")
returnValue("WOOSH")

Check warning on line 35 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L31-L35

Added lines #L31 - L35 were not covered by tests

def testBasics(self):
"""
Test that a normal inlineCallbacks works. Tests yielding a
deferred which callbacks, as well as a deferred errbacks. Also
ensures returning a final value works.
"""

return self._genBasics().addCallback(self.assertEqual, "WOOSH")

@inlineCallbacks
def _genBuggy(self):
yield getThing()
1 / 0

Check warning on line 49 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L49

Added line #L49 was not covered by tests

def testBuggy(self):
"""
Ensure that a buggy generator properly signals a Failure
condition on result deferred.
"""
return self.assertFailure(self._genBuggy(), ZeroDivisionError)

@inlineCallbacks
def _genNothing(self):
if False:
yield 1

def testNothing(self):
"""Test that a generator which never yields results in None."""

return self._genNothing().addCallback(self.assertEqual, None)

@inlineCallbacks
def _genHandledTerminalFailure(self):
try:
yield defer.fail(TerminalException("Handled Terminal Failure"))
except TerminalException:
pass

Check warning on line 73 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L73

Added line #L73 was not covered by tests

def testHandledTerminalFailure(self):
"""
Create a Deferred Generator which yields a Deferred which fails and
handles the exception which results. Assert that the Deferred
Generator does not errback its Deferred.
"""
return self._genHandledTerminalFailure().addCallback(self.assertEqual, None)

@inlineCallbacks
def _genHandledTerminalAsyncFailure(self, d):
try:
yield d
except TerminalException:
pass

Check warning on line 88 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L85-L88

Added lines #L85 - L88 were not covered by tests

def testHandledTerminalAsyncFailure(self):
"""
Just like testHandledTerminalFailure, only with a Deferred which fires
asynchronously with an error.
"""
d = defer.Deferred()
deferredGeneratorResultDeferred = self._genHandledTerminalAsyncFailure(d)
d.errback(TerminalException("Handled Terminal Failure"))
return deferredGeneratorResultDeferred.addCallback(self.assertEqual, None)

Check warning on line 98 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L96-L98

Added lines #L96 - L98 were not covered by tests

@inlineCallbacks
def _genStackUsage(self):
for x in range(5000):
# Test with yielding a deferred
yield defer.succeed(1)
returnValue(0)

Check warning on line 105 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L105

Added line #L105 was not covered by tests

def testStackUsage(self):
"""
Make sure we don't blow the stack when yielding immediately
available deferreds.
"""
return self._genStackUsage().addCallback(self.assertEqual, 0)

@inlineCallbacks
def _genStackUsage2(self):
for x in range(5000):
# Test with yielding a random value
yield 1
returnValue(0)

def testStackUsage2(self):
"""
Make sure we don't blow the stack when yielding immediately
available values.
"""
return self._genStackUsage2().addCallback(self.assertEqual, 0)

def testYieldNonDeferred(self):
"""
Ensure that yielding a non-deferred passes it back as the
result of the yield expression.
@return: A L{twisted.internet.defer.Deferred}
@rtype: L{twisted.internet.defer.Deferred}
"""

def _test():
yield 5
returnValue(5)

_test = inlineCallbacks(_test)

return _test().addCallback(self.assertEqual, 5)

def testReturnNoValue(self):
"""Ensure a standard python return results in a None result."""

def _noReturn():
yield 5
return

_noReturn = inlineCallbacks(_noReturn)

return _noReturn().addCallback(self.assertEqual, None)

def testReturnValue(self):
"""Ensure that returnValue works."""

def _return():
yield 5
returnValue(6)

_return = inlineCallbacks(_return)

return _return().addCallback(self.assertEqual, 6)

def test_nonGeneratorReturn(self):
"""
Ensure that C{TypeError} with a message about L{inlineCallbacks} is
raised when a non-generator returns something other than a generator.
"""

def _noYield():
return 5

_noYield = inlineCallbacks(_noYield)

self.assertIn("inlineCallbacks", str(self.assertRaises(TypeError, _noYield)))

def test_nonGeneratorReturnValue(self):
"""
Ensure that C{TypeError} with a message about L{inlineCallbacks} is
raised when a non-generator calls L{returnValue}.
"""

def _noYield():
returnValue(5)

_noYield = inlineCallbacks(_noYield)

self.assertIn("inlineCallbacks", str(self.assertRaises(TypeError, _noYield)))

def test_internalDefGenReturnValueDoesntLeak(self):
"""
When one inlineCallbacks calls another, the internal L{_DefGen_Return}
flow control exception raised by calling L{defer.returnValue} doesn't
leak into tracebacks captured in the caller.
"""
clock = task.Clock()

@inlineCallbacks

Check warning on line 201 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L201

Added line #L201 was not covered by tests
def _returns():
"""
This is the inner function using returnValue.
"""
yield task.deferLater(clock, 0)
returnValue("actual-value-not-used-for-the-test")

Check warning on line 207 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L206-L207

Added lines #L206 - L207 were not covered by tests

@inlineCallbacks

Check warning on line 209 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L209

Added line #L209 was not covered by tests
def _raises():
try:
yield _returns()
raise TerminalException("boom returnValue")
except TerminalException:
return traceback.format_exc()

Check warning on line 215 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L211-L215

Added lines #L211 - L215 were not covered by tests

d = _raises()
clock.advance(0)
tb = self.successResultOf(d)

Check warning on line 219 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L217-L219

Added lines #L217 - L219 were not covered by tests

# The internal exception is not in the traceback.
self.assertNotIn("_DefGen_Return", tb)

Check warning on line 222 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L222

Added line #L222 was not covered by tests
# No other extra exception is in the traceback.
self.assertNotIn(

Check warning on line 224 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L224

Added line #L224 was not covered by tests
"During handling of the above exception, another exception occurred", tb
)
# Our targeted exception is in the traceback
self.assertIn("test_defgen.TerminalException: boom returnValue", tb)

Check warning on line 228 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L228

Added line #L228 was not covered by tests

def test_internalStopIterationDoesntLeak(self):
"""
When one inlineCallbacks calls another, the internal L{StopIteration}
flow control exception generated when the inner generator returns
doesn't leak into tracebacks captured in the caller.
This is similar to C{test_internalDefGenReturnValueDoesntLeak} but the
inner function uses the "normal" return statemement rather than the
C{returnValue} helper.
"""
clock = task.Clock()

@inlineCallbacks

Check warning on line 242 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L242

Added line #L242 was not covered by tests
def _returns():
yield task.deferLater(clock, 0)
return 6

Check warning on line 245 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L244-L245

Added lines #L244 - L245 were not covered by tests

@inlineCallbacks

Check warning on line 247 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L247

Added line #L247 was not covered by tests
def _raises():
try:
yield _returns()
raise TerminalException("boom normal return")
except TerminalException:
return traceback.format_exc()

Check warning on line 253 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L249-L253

Added lines #L249 - L253 were not covered by tests

d = _raises()
clock.advance(0)
tb = self.successResultOf(d)

Check warning on line 257 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L255-L257

Added lines #L255 - L257 were not covered by tests

# The internal exception is not in the traceback.
self.assertNotIn("StopIteration", tb)

Check warning on line 260 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L260

Added line #L260 was not covered by tests
# No other extra exception is in the traceback.
self.assertNotIn(

Check warning on line 262 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L262

Added line #L262 was not covered by tests
"During handling of the above exception, another exception occurred", tb
)
# Our targeted exception is in the traceback
self.assertIn("test_defgen.TerminalException: boom normal return", tb)

Check warning on line 266 in src/twisted/internet/test/test_inlinecb.py

View check run for this annotation

Codecov / codecov/patch

src/twisted/internet/test/test_inlinecb.py#L266

Added line #L266 was not covered by tests


class StopIterationReturnTests(TestCase):
"""
On Python 3.4 and newer generator functions may use the C{return} statement
Expand Down

0 comments on commit 1debeec

Please sign in to comment.