mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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. ........
This commit is contained in:
parent
2e510fb920
commit
7d2ff884ee
5 changed files with 130 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue