diff --git a/src/twisted/internet/_glibbase.py b/src/twisted/internet/_glibbase.py index 8686e3cf2e7..4fc5271e75b 100644 --- a/src/twisted/internet/_glibbase.py +++ b/src/twisted/internet/_glibbase.py @@ -354,8 +354,8 @@ def simulate(self): if self._simtag is not None: self._source_remove(self._simtag) self.iterate() - timeout = min(self.timeout(), 0.01) - if timeout is None: + timeout = self.timeout() + if timeout is None or timeout > 0.01: timeout = 0.01 self._simtag = self._timeout_add( int(timeout * 1000), diff --git a/src/twisted/internet/test/test_glibbase.py b/src/twisted/internet/test/test_glibbase.py index b391d47e4c8..b6b14b8bfaa 100644 --- a/src/twisted/internet/test/test_glibbase.py +++ b/src/twisted/internet/test/test_glibbase.py @@ -65,3 +65,36 @@ def test_ensureFailsWhenImported(self): ) self.assertEqual(modules, {"m2": module}) self.assertEqual(e.args, ("A message.",)) + + +try: + from twisted.internet import gireactor as _gireactor +except ImportError: + gireactor = None +else: + gireactor = _gireactor + +missingGlibReactor = None +if gireactor is None: + missingGlibReactor = "gi reactor not available" + + +class GlibReactorBaseTests(TestCase): + """ + Tests for the private C{twisted.internet._glibbase.GlibReactorBase} + done via the public C{twisted.internet.gireactor.PortableGIReactor} + """ + + skip = missingGlibReactor + + def test_simulate(self): + """ + C{simulate} can be called without raising any errors when there are + no delayed calls for the reactor and hence there is no defined sleep + period. + """ + sut = gireactor.PortableGIReactor(usegtk=False) + # Double check that reactor has no sleep period. + self.assertIs(None, sut.timeout()) + + sut.simulate() diff --git a/src/twisted/newsfragments/9660.bugfix b/src/twisted/newsfragments/9660.bugfix new file mode 100644 index 00000000000..f5d56197ea7 --- /dev/null +++ b/src/twisted/newsfragments/9660.bugfix @@ -0,0 +1 @@ +twisted.internet.glibbase.simulate no longer raises TypeError with no timeout on Python 3. \ No newline at end of file