summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2007-11-30 14:35:04 (GMT)
committerChristian Heimes <christian@cheimes.de>2007-11-30 14:35:04 (GMT)
commit7d2ff884eeb636fcd30ebd2f9886c4b46e8545bc (patch)
tree464092cc4b9f9ef6b4a32c7fb5d5bfbfb1131c9d
parent2e510fb9202977d93cc364e0c661769ea4a8cbbc (diff)
downloadcpython-7d2ff884eeb636fcd30ebd2f9886c4b46e8545bc.zip
cpython-7d2ff884eeb636fcd30ebd2f9886c4b46e8545bc.tar.gz
cpython-7d2ff884eeb636fcd30ebd2f9886c4b46e8545bc.tar.bz2
Merged revisions 59226-59233 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r59228 | amaury.forgeotdarc | 2007-11-29 21:24:36 +0100 (Thu, 29 Nov 2007) | 4 lines vc2008: Move python.vcproj first in the solution file, so that it becomes the default startup project when opening the file for the first time. ........ r59230 | georg.brandl | 2007-11-30 00:00:03 +0100 (Fri, 30 Nov 2007) | 3 lines Add more examples to the wsgiref docs. From GHOP by Josip Dzolonga. ........ r59231 | amaury.forgeotdarc | 2007-11-30 00:35:25 +0100 (Fri, 30 Nov 2007) | 7 lines Issue #1402: PyInterpreterState_Clear() may still invoke user code (in deallocation of running threads, for example), so the PyGILState_Release() function must still be functional. On the other hand, _PyGILState_Fini() only frees memory, and can be called later. Backport candidate, but only after some experts comment on it. ........
-rw-r--r--Doc/ACKS.txt1
-rw-r--r--Doc/library/wsgiref.rst89
-rw-r--r--Lib/test/test_threading.py34
-rw-r--r--PCbuild9/pcbuild.sln4
-rw-r--r--Python/pythonrun.c10
5 files changed, 130 insertions, 8 deletions
diff --git a/Doc/ACKS.txt b/Doc/ACKS.txt
index 1e2c4ec..52aa794 100644
--- a/Doc/ACKS.txt
+++ b/Doc/ACKS.txt
@@ -41,6 +41,7 @@ docs@python.org), and we'll be glad to correct the problem.
* L. Peter Deutsch
* Robert Donohue
* Fred L. Drake, Jr.
+* Josip Dzolonga
* Jeff Epler
* Michael Ernst
* Blame Andy Eskilsson
diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst
index 73acf84..0118032 100644
--- a/Doc/library/wsgiref.rst
+++ b/Doc/library/wsgiref.rst
@@ -112,6 +112,30 @@ parameter expect a WSGI-compliant dictionary to be supplied; please see
applications to set up dummy environments. It should NOT be used by actual WSGI
servers or applications, since the data is fake!
+ Example usage::
+
+ from wsgiref.util import setup_testing_defaults
+ from wsgiref.simple_server import make_server
+
+ # A relatively simple WSGI application. It's going to print out the
+ # environment dictionary after being updated by setup_testing_defaults
+ def simple_app(environ, start_response):
+ setup_testing_defaults(environ)
+
+ status = '200 OK'
+ headers = [('Content-type', 'text/plain')]
+
+ start_response(status, headers)
+
+ ret = ["%s: %s\n" % (key, value)
+ for key, value in environ.iteritems()]
+ return ret
+
+ httpd = make_server('', 8000, simple_app)
+ print "Serving on port 8000..."
+ httpd.serve_forever()
+
+
In addition to the environment functions above, the :mod:`wsgiref.util` module
also provides these miscellaneous utilities:
@@ -135,6 +159,19 @@ also provides these miscellaneous utilities:
:meth:`close` method, and it will invoke the *filelike* object's :meth:`close`
method when called.
+ Example usage::
+
+ from StringIO import StringIO
+ from wsgiref.util import FileWrapper
+
+ # We're using a StringIO-buffer for as the file-like object
+ filelike = StringIO("This is an example file-like object"*10)
+ wrapper = FileWrapper(filelike, blksize=5)
+
+ for chunk in wrapper:
+ print chunk
+
+
:mod:`wsgiref.headers` -- WSGI response header tools
----------------------------------------------------
@@ -250,7 +287,7 @@ request. (E.g., using the :func:`shift_path_info` function from
httpd.serve_forever()
# Alternative: serve one request, then exit
- ##httpd.handle_request()
+ httpd.handle_request()
.. function:: demo_app(environ, start_response)
@@ -371,6 +408,29 @@ Paste" library.
``sys.stderr`` (*not* ``wsgi.errors``, unless they happen to be the same
object).
+ Example usage::
+
+ from wsgiref.validate import validator
+ from wsgiref.simple_server import make_server
+
+ # Our callable object which is intentionally not compilant to the
+ # standard, so the validator is going to break
+ def simple_app(environ, start_response):
+ status = '200 OK' # HTTP Status
+ headers = [('Content-type', 'text/plain')] # HTTP Headers
+ start_response(status, headers)
+
+ # This is going to break because we need to return a list, and
+ # the validator is going to inform us
+ return "Hello World"
+
+ # This is the application wrapped in a validator
+ validator_app = validator(simple_app)
+
+ httpd = make_server('', 8000, validator_app)
+ print "Listening on port 8000...."
+ httpd.serve_forever()
+
:mod:`wsgiref.handlers` -- server/gateway base classes
------------------------------------------------------
@@ -637,3 +697,30 @@ input, output, and error streams.
If :attr:`origin_server` is true, this string attribute is used to set the HTTP
version of the response set to the client. It defaults to ``"1.0"``.
+
+Examples
+--------
+
+This is a working "Hello World" WSGI application::
+
+ from wsgiref.simple_server import make_server
+
+ # Every WSGI application must have an application object - a callable
+ # object that accepts two arguments. For that purpose, we're going to
+ # use a function (note that you're not limited to a function, you can
+ # use a class for example). The first argument passed to the function
+ # is a dictionary containing CGI-style envrironment variables and the
+ # second variable is the callable object (see PEP333)
+ def hello_world_app(environ, start_response):
+ status = '200 OK' # HTTP Status
+ headers = [('Content-type', 'text/plain')] # HTTP Headers
+ start_response(status, headers)
+
+ # The returned object is going to be printed
+ return ["Hello World"]
+
+ httpd = make_server('', 8000, hello_world_app)
+ print "Serving on port 8000..."
+
+ # Serve until process is killed
+ httpd.serve_forever()
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index b76cea1..e5ed201 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -202,6 +202,40 @@ class ThreadTests(unittest.TestCase):
t.join()
# else the thread is still running, and we have no way to kill it
+ def test_finalize_runnning_thread(self):
+ # Issue 1402: the PyGILState_Ensure / _Release functions may be called
+ # very late on python exit: on deallocation of a running thread for
+ # example.
+ try:
+ import ctypes
+ except ImportError:
+ if verbose:
+ print("test_finalize_with_runnning_thread can't import ctypes")
+ return # can't do anything
+
+ import subprocess
+ rc = subprocess.call([sys.executable, "-c", """if 1:
+ import ctypes, sys, time, thread
+
+ # Module globals are cleared before __del__ is run
+ # So we save the functions in class dict
+ class C:
+ ensure = ctypes.pythonapi.PyGILState_Ensure
+ release = ctypes.pythonapi.PyGILState_Release
+ def __del__(self):
+ state = self.ensure()
+ self.release(state)
+
+ def waitingThread():
+ x = C()
+ time.sleep(100)
+
+ thread.start_new_thread(waitingThread, ())
+ time.sleep(1) # be sure the other thread is waiting
+ sys.exit(42)
+ """])
+ self.assertEqual(rc, 42)
+
class ThreadingExceptionTests(unittest.TestCase):
# A RuntimeError should be raised if Thread.start() is called
# multiple times.
diff --git a/PCbuild9/pcbuild.sln b/PCbuild9/pcbuild.sln
index 1625875..d81c3b4 100644
--- a/PCbuild9/pcbuild.sln
+++ b/PCbuild9/pcbuild.sln
@@ -1,13 +1,13 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
ProjectSection(ProjectDependencies) = postProject
{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
ProjectSection(ProjectDependencies) = postProject
{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 5766b23..08b0d83 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -467,11 +467,6 @@ Py_Finalize(void)
_Py_PrintReferences(stderr);
#endif /* Py_TRACE_REFS */
- /* Cleanup auto-thread-state */
-#ifdef WITH_THREAD
- _PyGILState_Fini();
-#endif /* WITH_THREAD */
-
/* Clear interpreter state */
PyInterpreterState_Clear(interp);
@@ -483,6 +478,11 @@ Py_Finalize(void)
_PyExc_Fini();
+ /* Cleanup auto-thread-state */
+#ifdef WITH_THREAD
+ _PyGILState_Fini();
+#endif /* WITH_THREAD */
+
/* Delete current thread */
PyThreadState_Swap(NULL);
PyInterpreterState_Delete(interp);