[Python-checkins] r86633 - in python/branches/py3k: Doc/library/inspect.rst Doc/whatsnew/3.2.rst Lib/inspect.py Lib/test/test_inspect.py Misc/NEWS
nick.coghlan
python-checkins at python.org
Sun Nov 21 04:44:04 CET 2010
Author: nick.coghlan
Date: Sun Nov 21 04:44:04 2010
New Revision: 86633
Log:
Issue #10220: Add inspect.getgeneratorstate(). Initial patch by Rodolpho Eckhardt
Modified:
python/branches/py3k/Doc/library/inspect.rst
python/branches/py3k/Doc/whatsnew/3.2.rst
python/branches/py3k/Lib/inspect.py
python/branches/py3k/Lib/test/test_inspect.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/inspect.rst
==============================================================================
--- python/branches/py3k/Doc/library/inspect.rst (original)
+++ python/branches/py3k/Doc/library/inspect.rst Sun Nov 21 04:44:04 2010
@@ -620,3 +620,25 @@
# in which case the descriptor itself will
# have to do
pass
+
+Current State of a Generator
+----------------------------
+
+When implementing coroutine schedulers and for other advanced uses of
+generators, it is useful to determine whether a generator is currently
+executing, is waiting to start or resume or execution, or has already
+terminated. func:`getgeneratorstate` allows the current state of a
+generator to be determined easily.
+
+.. function:: getgeneratorstate(generator)
+
+ Get current state of a generator-iterator.
+
+ Possible states are:
+ GEN_CREATED: Waiting to start execution.
+ GEN_RUNNING: Currently being executed by the interpreter.
+ GEN_SUSPENDED: Currently suspended at a yield expression.
+ GEN_CLOSED: Execution has completed.
+
+
+
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Nov 21 04:44:04 2010
@@ -554,6 +554,14 @@
(Contributed by R. David Murray, :issue:`10321`.)
+* The :mod:`inspect` module has a new function :func:`getgenatorstate`
+ to easily identify the current state of a generator as one of
+ ``GEN_CREATED``, ``GEN_RUNNING``, ``GEN_SUSPENDED`` or ``GEN_CLOSED``.
+
+ (Contributed by Rodolpho Eckhardt and Nick Coghlan, :issue:`10220`.)
+
+.. XXX: Mention inspect.getattr_static (Michael Foord)
+
Multi-threading
===============
Modified: python/branches/py3k/Lib/inspect.py
==============================================================================
--- python/branches/py3k/Lib/inspect.py (original)
+++ python/branches/py3k/Lib/inspect.py Sun Nov 21 04:44:04 2010
@@ -1128,3 +1128,23 @@
if default is not _sentinel:
return default
raise AttributeError(attr)
+
+
+GEN_CREATED, GEN_RUNNING, GEN_SUSPENDED, GEN_CLOSED = range(4)
+
+def getgeneratorstate(generator):
+ """Get current state of a generator-iterator.
+
+ Possible states are:
+ GEN_CREATED: Waiting to start execution.
+ GEN_RUNNING: Currently being executed by the interpreter.
+ GEN_SUSPENDED: Currently suspended at a yield expression.
+ GEN_CLOSED: Execution has completed.
+ """
+ if generator.gi_running:
+ return GEN_RUNNING
+ if generator.gi_frame is None:
+ return GEN_CLOSED
+ if generator.gi_frame.f_lasti == -1:
+ return GEN_CREATED
+ return GEN_SUSPENDED
Modified: python/branches/py3k/Lib/test/test_inspect.py
==============================================================================
--- python/branches/py3k/Lib/test/test_inspect.py (original)
+++ python/branches/py3k/Lib/test/test_inspect.py Sun Nov 21 04:44:04 2010
@@ -887,12 +887,57 @@
self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
+class TestGetGeneratorState(unittest.TestCase):
+
+ def setUp(self):
+ def number_generator():
+ for number in range(5):
+ yield number
+ self.generator = number_generator()
+
+ def _generatorstate(self):
+ return inspect.getgeneratorstate(self.generator)
+
+ def test_created(self):
+ self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
+
+ def test_suspended(self):
+ next(self.generator)
+ self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
+
+ def test_closed_after_exhaustion(self):
+ for i in self.generator:
+ pass
+ self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
+
+ def test_closed_after_immediate_exception(self):
+ with self.assertRaises(RuntimeError):
+ self.generator.throw(RuntimeError)
+ self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
+
+ def test_running(self):
+ # As mentioned on issue #10220, checking for the RUNNING state only
+ # makes sense inside the generator itself.
+ # The following generator checks for this by using the closure's
+ # reference to self and the generator state checking helper method
+ def running_check_generator():
+ for number in range(5):
+ self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
+ yield number
+ self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
+ self.generator = running_check_generator()
+ # Running up to the first yield
+ next(self.generator)
+ # Running after the first yield
+ next(self.generator)
+
+
def test_main():
run_unittest(
TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
TestGetcallargsFunctions, TestGetcallargsMethods,
- TestGetcallargsUnboundMethods, TestGetattrStatic
+ TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState
)
if __name__ == "__main__":
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Nov 21 04:44:04 2010
@@ -32,6 +32,9 @@
Library
-------
+- Issue #10220: Added inspect.getgeneratorstate. Initial patch by
+ Rodolpho Eckhardt.
+
- Issue #10453: compileall now uses argparse instead of getopt, and thus
provides clean output when called with '-h'.
More information about the Python-checkins
mailing list