Skip to content

Commit 7d2ff88

Browse files
committed
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. ........
1 parent 2e510fb commit 7d2ff88

File tree

5 files changed

+130
-8
lines changed

5 files changed

+130
-8
lines changed

Doc/ACKS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ docs@python.org), and we'll be glad to correct the problem.
4141
* L. Peter Deutsch
4242
* Robert Donohue
4343
* Fred L. Drake, Jr.
44+
* Josip Dzolonga
4445
* Jeff Epler
4546
* Michael Ernst
4647
* Blame Andy Eskilsson

Doc/library/wsgiref.rst

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,30 @@ parameter expect a WSGI-compliant dictionary to be supplied; please see
112112
applications to set up dummy environments. It should NOT be used by actual WSGI
113113
servers or applications, since the data is fake!
114114

115+
Example usage::
116+
117+
from wsgiref.util import setup_testing_defaults
118+
from wsgiref.simple_server import make_server
119+
120+
# A relatively simple WSGI application. It's going to print out the
121+
# environment dictionary after being updated by setup_testing_defaults
122+
def simple_app(environ, start_response):
123+
setup_testing_defaults(environ)
124+
125+
status = '200 OK'
126+
headers = [('Content-type', 'text/plain')]
127+
128+
start_response(status, headers)
129+
130+
ret = ["%s: %s\n" % (key, value)
131+
for key, value in environ.iteritems()]
132+
return ret
133+
134+
httpd = make_server('', 8000, simple_app)
135+
print "Serving on port 8000..."
136+
httpd.serve_forever()
137+
138+
115139
In addition to the environment functions above, the :mod:`wsgiref.util` module
116140
also provides these miscellaneous utilities:
117141

@@ -135,6 +159,19 @@ also provides these miscellaneous utilities:
135159
:meth:`close` method, and it will invoke the *filelike* object's :meth:`close`
136160
method when called.
137161

162+
Example usage::
163+
164+
from StringIO import StringIO
165+
from wsgiref.util import FileWrapper
166+
167+
# We're using a StringIO-buffer for as the file-like object
168+
filelike = StringIO("This is an example file-like object"*10)
169+
wrapper = FileWrapper(filelike, blksize=5)
170+
171+
for chunk in wrapper:
172+
print chunk
173+
174+
138175

139176
:mod:`wsgiref.headers` -- WSGI response header tools
140177
----------------------------------------------------
@@ -250,7 +287,7 @@ request. (E.g., using the :func:`shift_path_info` function from
250287
httpd.serve_forever()
251288

252289
# Alternative: serve one request, then exit
253-
##httpd.handle_request()
290+
httpd.handle_request()
254291

255292

256293
.. function:: demo_app(environ, start_response)
@@ -371,6 +408,29 @@ Paste" library.
371408
``sys.stderr`` (*not* ``wsgi.errors``, unless they happen to be the same
372409
object).
373410

411+
Example usage::
412+
413+
from wsgiref.validate import validator
414+
from wsgiref.simple_server import make_server
415+
416+
# Our callable object which is intentionally not compilant to the
417+
# standard, so the validator is going to break
418+
def simple_app(environ, start_response):
419+
status = '200 OK' # HTTP Status
420+
headers = [('Content-type', 'text/plain')] # HTTP Headers
421+
start_response(status, headers)
422+
423+
# This is going to break because we need to return a list, and
424+
# the validator is going to inform us
425+
return "Hello World"
426+
427+
# This is the application wrapped in a validator
428+
validator_app = validator(simple_app)
429+
430+
httpd = make_server('', 8000, validator_app)
431+
print "Listening on port 8000...."
432+
httpd.serve_forever()
433+
374434

375435
:mod:`wsgiref.handlers` -- server/gateway base classes
376436
------------------------------------------------------
@@ -637,3 +697,30 @@ input, output, and error streams.
637697
If :attr:`origin_server` is true, this string attribute is used to set the HTTP
638698
version of the response set to the client. It defaults to ``"1.0"``.
639699

700+
701+
Examples
702+
--------
703+
704+
This is a working "Hello World" WSGI application::
705+
706+
from wsgiref.simple_server import make_server
707+
708+
# Every WSGI application must have an application object - a callable
709+
# object that accepts two arguments. For that purpose, we're going to
710+
# use a function (note that you're not limited to a function, you can
711+
# use a class for example). The first argument passed to the function
712+
# is a dictionary containing CGI-style envrironment variables and the
713+
# second variable is the callable object (see PEP333)
714+
def hello_world_app(environ, start_response):
715+
status = '200 OK' # HTTP Status
716+
headers = [('Content-type', 'text/plain')] # HTTP Headers
717+
start_response(status, headers)
718+
719+
# The returned object is going to be printed
720+
return ["Hello World"]
721+
722+
httpd = make_server('', 8000, hello_world_app)
723+
print "Serving on port 8000..."
724+
725+
# Serve until process is killed
726+
httpd.serve_forever()

Lib/test/test_threading.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,40 @@ def run(self):
202202
t.join()
203203
# else the thread is still running, and we have no way to kill it
204204

205+
def test_finalize_runnning_thread(self):
206+
# Issue 1402: the PyGILState_Ensure / _Release functions may be called
207+
# very late on python exit: on deallocation of a running thread for
208+
# example.
209+
try:
210+
import ctypes
211+
except ImportError:
212+
if verbose:
213+
print("test_finalize_with_runnning_thread can't import ctypes")
214+
return # can't do anything
215+
216+
import subprocess
217+
rc = subprocess.call([sys.executable, "-c", """if 1:
218+
import ctypes, sys, time, thread
219+
220+
# Module globals are cleared before __del__ is run
221+
# So we save the functions in class dict
222+
class C:
223+
ensure = ctypes.pythonapi.PyGILState_Ensure
224+
release = ctypes.pythonapi.PyGILState_Release
225+
def __del__(self):
226+
state = self.ensure()
227+
self.release(state)
228+
229+
def waitingThread():
230+
x = C()
231+
time.sleep(100)
232+
233+
thread.start_new_thread(waitingThread, ())
234+
time.sleep(1) # be sure the other thread is waiting
235+
sys.exit(42)
236+
"""])
237+
self.assertEqual(rc, 42)
238+
205239
class ThreadingExceptionTests(unittest.TestCase):
206240
# A RuntimeError should be raised if Thread.start() is called
207241
# multiple times.

PCbuild9/pcbuild.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
Microsoft Visual Studio Solution File, Format Version 10.00
22
# Visual Studio 2008
3-
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
4-
EndProject
53
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
64
ProjectSection(ProjectDependencies) = postProject
75
{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}
86
{E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}
97
EndProjectSection
108
EndProject
9+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}"
10+
EndProject
1111
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
1212
ProjectSection(ProjectDependencies) = postProject
1313
{F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E}

Python/pythonrun.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,6 @@ Py_Finalize(void)
467467
_Py_PrintReferences(stderr);
468468
#endif /* Py_TRACE_REFS */
469469

470-
/* Cleanup auto-thread-state */
471-
#ifdef WITH_THREAD
472-
_PyGILState_Fini();
473-
#endif /* WITH_THREAD */
474-
475470
/* Clear interpreter state */
476471
PyInterpreterState_Clear(interp);
477472

@@ -483,6 +478,11 @@ Py_Finalize(void)
483478

484479
_PyExc_Fini();
485480

481+
/* Cleanup auto-thread-state */
482+
#ifdef WITH_THREAD
483+
_PyGILState_Fini();
484+
#endif /* WITH_THREAD */
485+
486486
/* Delete current thread */
487487
PyThreadState_Swap(NULL);
488488
PyInterpreterState_Delete(interp);

0 commit comments

Comments
 (0)