Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2f1019e

Browse files
committed
Merged revisions 59441-59449 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r59442 | georg.brandl | 2007-12-09 22:15:07 +0100 (Sun, 09 Dec 2007) | 5 lines Two fixes in DocXMLRPCServer: * remove parameter default that didn't make sense * properly escape values in output Thanks to Jeff Wheeler from GHOP! ........ r59444 | georg.brandl | 2007-12-09 23:38:26 +0100 (Sun, 09 Dec 2007) | 2 lines Add Jeff Wheeler. ........ r59445 | georg.brandl | 2007-12-09 23:39:12 +0100 (Sun, 09 Dec 2007) | 2 lines Add DocXMLRPCServer test from GHOP task #136, written by Jeff Wheeler. ........ r59447 | christian.heimes | 2007-12-10 16:12:41 +0100 (Mon, 10 Dec 2007) | 1 line Added wide char api variants of getch and putch to msvcrt module. The wide char methods are required to fix #1578 in py3k. I figured out that they might be useful in 2.6, too. ........ r59448 | christian.heimes | 2007-12-10 16:39:09 +0100 (Mon, 10 Dec 2007) | 1 line Stupid save all didn't safe it all ... ........
1 parent 0ded5b5 commit 2f1019e

5 files changed

Lines changed: 258 additions & 28 deletions

File tree

Doc/library/msvcrt.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ this in the implementation of the :func:`getpass` function.
1616
Further documentation on these functions can be found in the Platform API
1717
documentation.
1818

19+
The module implements both the normal and wide char variants of the console I/O
20+
api. The normal API deals only with ASCII characters and is of limited use
21+
for internationalized applications. The wide char API should be used where
22+
ever possible
1923

2024
.. _msvcrt-files:
2125

@@ -94,23 +98,51 @@ Console I/O
9498
return the keycode. The :kbd:`Control-C` keypress cannot be read with this
9599
function.
96100

101+
102+
.. function:: getwch()
103+
104+
Wide char variant of `func:getch`, returns unicode.
105+
106+
..versionadded:: 2.6
107+
97108

98109
.. function:: getche()
99110

100111
Similar to :func:`getch`, but the keypress will be echoed if it represents a
101112
printable character.
102113

103114

115+
.. function:: getwche()
116+
117+
Wide char variant of `func:getche`, returns unicode.
118+
119+
..versionadded:: 2.6
120+
121+
104122
.. function:: putch(char)
105123

106124
Print the character *char* to the console without buffering.
107125

126+
127+
.. function:: putwch(unicode_char)
128+
129+
Wide char variant of `func:putch`, accepts unicode.
130+
131+
..versionadded:: 2.6
132+
108133

109134
.. function:: ungetch(char)
110135

111136
Cause the character *char* to be "pushed back" into the console buffer; it will
112137
be the next character read by :func:`getch` or :func:`getche`.
113138

139+
140+
.. function:: ungetwch(unicode_char)
141+
142+
Wide char variant of `func:ungetch`, accepts unicode.
143+
144+
..versionadded:: 2.6
145+
114146

115147
.. _msvcrt-other:
116148

Lib/DocXMLRPCServer.py

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
6464
results.append(escape(text[here:]))
6565
return ''.join(results)
6666

67-
def docroutine(self, object, name=None, mod=None,
67+
def docroutine(self, object, name, mod=None,
6868
funcs={}, classes={}, methods={}, cl=None):
6969
"""Produce HTML documentation for a function or method object."""
7070

7171
anchor = (cl and cl.__name__ or '') + '-' + name
7272
note = ''
7373

74-
title = '<a name="%s"><strong>%s</strong></a>' % (anchor, name)
74+
title = '<a name="%s"><strong>%s</strong></a>' % (
75+
self.escape(anchor), self.escape(name))
7576

7677
if inspect.ismethod(object):
7778
args, varargs, varkw, defaults = inspect.getargspec(object)
@@ -113,6 +114,7 @@ def docserver(self, server_name, package_documentation, methods):
113114
fdict[key] = '#-' + key
114115
fdict[value] = fdict[key]
115116

117+
server_name = self.escape(server_name)
116118
head = '<big><big><strong>%s</strong></big></big>' % server_name
117119
result = self.heading(head, '#ffffff', '#7799ee')
118120

@@ -280,29 +282,3 @@ def handle_get(self):
280282
def __init__(self):
281283
CGIXMLRPCRequestHandler.__init__(self)
282284
XMLRPCDocGenerator.__init__(self)
283-
284-
if __name__ == '__main__':
285-
def deg_to_rad(deg):
286-
"""deg_to_rad(90) => 1.5707963267948966
287-
288-
Converts an angle in degrees to an angle in radians"""
289-
import math
290-
return deg * math.pi / 180
291-
292-
server = DocXMLRPCServer(("localhost", 8000))
293-
294-
server.set_server_title("Math Server")
295-
server.set_server_name("Math XML-RPC Server")
296-
server.set_server_documentation("""This server supports various mathematical functions.
297-
298-
You can use it from Python as follows:
299-
300-
>>> from xmlrpclib import ServerProxy
301-
>>> s = ServerProxy("http://localhost:8000")
302-
>>> s.deg_to_rad(90.0)
303-
1.5707963267948966""")
304-
305-
server.register_function(deg_to_rad)
306-
server.register_introspection_functions()
307-
308-
server.serve_forever()

Lib/test/test_docxmlrpc.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
from DocXMLRPCServer import DocXMLRPCServer
2+
import httplib
3+
from test import test_support
4+
import threading
5+
import time
6+
import unittest
7+
import xmlrpclib
8+
9+
PORT = None
10+
11+
def server(evt, numrequests):
12+
try:
13+
serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
14+
15+
global PORT
16+
PORT = serv.socket.getsockname()[1]
17+
18+
# Add some documentation
19+
serv.set_server_title("DocXMLRPCServer Test Documentation")
20+
serv.set_server_name("DocXMLRPCServer Test Docs")
21+
serv.set_server_documentation(
22+
"""This is an XML-RPC server's documentation, but the server can be used by
23+
POSTing to /RPC2. Try self.add, too.""")
24+
25+
# Create and register classes and functions
26+
class TestClass(object):
27+
def test_method(self, arg):
28+
"""Test method's docs. This method truly does very little."""
29+
self.arg = arg
30+
31+
serv.register_introspection_functions()
32+
serv.register_instance(TestClass())
33+
34+
def add(x, y):
35+
"""Add two instances together. This follows PEP008, but has nothing
36+
to do with RFC1952. Case should matter: pEp008 and rFC1952. Things
37+
that start with http and ftp should be auto-linked, too:
38+
http://google.com.
39+
"""
40+
return x + y
41+
42+
serv.register_function(add)
43+
serv.register_function(lambda x, y: x-y)
44+
45+
while numrequests > 0:
46+
serv.handle_request()
47+
numrequests -= 1
48+
except socket.timeout:
49+
pass
50+
finally:
51+
serv.server_close()
52+
PORT = None
53+
evt.set()
54+
55+
class DocXMLRPCHTTPGETServer(unittest.TestCase):
56+
def setUp(self):
57+
# Enable server feedback
58+
DocXMLRPCServer._send_traceback_header = True
59+
60+
self.evt = threading.Event()
61+
threading.Thread(target=server, args=(self.evt, 1)).start()
62+
63+
# wait for port to be assigned
64+
n = 1000
65+
while n > 0 and PORT is None:
66+
time.sleep(0.001)
67+
n -= 1
68+
69+
self.client = httplib.HTTPConnection("localhost:%d" % PORT)
70+
71+
def tearDown(self):
72+
self.client.close()
73+
74+
self.evt.wait()
75+
76+
# Disable server feedback
77+
DocXMLRPCServer._send_traceback_header = False
78+
79+
def test_valid_get_response(self):
80+
self.client.request("GET", "/")
81+
response = self.client.getresponse()
82+
83+
self.assertEqual(response.status, 200)
84+
self.assertEqual(response.getheader("Content-type"), "text/html")
85+
86+
# Server throws an exception if we don't start to read the data
87+
response.read()
88+
89+
def test_invalid_get_response(self):
90+
self.client.request("GET", "/spam")
91+
response = self.client.getresponse()
92+
93+
self.assertEqual(response.status, 404)
94+
self.assertEqual(response.getheader("Content-type"), "text/plain")
95+
96+
response.read()
97+
98+
def test_lambda(self):
99+
"""Test that lambda functionality stays the same. The output produced
100+
currently is, I suspect invalid because of the unencoded brackets in the
101+
HTML, "<lambda>".
102+
103+
The subtraction lambda method is tested.
104+
"""
105+
self.client.request("GET", "/")
106+
response = self.client.getresponse()
107+
108+
self.assert_(
109+
"""<dl><dt><a name="-&lt;lambda&gt;"><strong>&lt;lambda&gt;</strong></a>(x, y)</dt></dl>"""
110+
in response.read())
111+
112+
def test_autolinking(self):
113+
"""Test that the server correctly automatically wraps references to PEPS
114+
and RFCs with links, and that it linkifies text starting with http or
115+
ftp protocol prefixes.
116+
117+
The documentation for the "add" method contains the test material.
118+
"""
119+
self.client.request("GET", "/")
120+
response = self.client.getresponse()
121+
122+
self.assert_( # This is ugly ... how can it be made better?
123+
"""<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd><tt>Add&nbsp;two&nbsp;instances&nbsp;together.&nbsp;This&nbsp;follows&nbsp;<a href="http://www.python.org/peps/pep-0008.html">PEP008</a>,&nbsp;but&nbsp;has&nbsp;nothing<br>\nto&nbsp;do&nbsp;with&nbsp;<a href="http://www.rfc-editor.org/rfc/rfc1952.txt">RFC1952</a>.&nbsp;Case&nbsp;should&nbsp;matter:&nbsp;pEp008&nbsp;and&nbsp;rFC1952.&nbsp;&nbsp;Things<br>\nthat&nbsp;start&nbsp;with&nbsp;http&nbsp;and&nbsp;ftp&nbsp;should&nbsp;be&nbsp;auto-linked,&nbsp;too:<br>\n<a href="http://google.com">http://google.com</a>.</tt></dd></dl>"""
124+
in response.read())
125+
126+
def test_system_methods(self):
127+
"""Test the precense of three consecutive system.* methods.
128+
129+
This also tests their use of parameter type recognition and the systems
130+
related to that process.
131+
"""
132+
self.client.request("GET", "/")
133+
response = self.client.getresponse()
134+
135+
self.assert_(
136+
"""<dl><dt><a name="-system.listMethods"><strong>system.listMethods</strong></a>()</dt><dd><tt><a href="#-system.listMethods">system.listMethods</a>()&nbsp;=&gt;&nbsp;[\'add\',&nbsp;\'subtract\',&nbsp;\'multiple\']<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;methods&nbsp;supported&nbsp;by&nbsp;the&nbsp;server.</tt></dd></dl>\n <dl><dt><a name="-system.methodHelp"><strong>system.methodHelp</strong></a>(method_name)</dt><dd><tt><a href="#-system.methodHelp">system.methodHelp</a>(\'add\')&nbsp;=&gt;&nbsp;"Adds&nbsp;two&nbsp;integers&nbsp;together"<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;string&nbsp;containing&nbsp;documentation&nbsp;for&nbsp;the&nbsp;specified&nbsp;method.</tt></dd></dl>\n <dl><dt><a name="-system.methodSignature"><strong>system.methodSignature</strong></a>(method_name)</dt><dd><tt><a href="#-system.methodSignature">system.methodSignature</a>(\'add\')&nbsp;=&gt;&nbsp;[double,&nbsp;int,&nbsp;int]<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;describing&nbsp;the&nbsp;signature&nbsp;of&nbsp;the&nbsp;method.&nbsp;In&nbsp;the<br>\nabove&nbsp;example,&nbsp;the&nbsp;add&nbsp;method&nbsp;takes&nbsp;two&nbsp;integers&nbsp;as&nbsp;arguments<br>\nand&nbsp;returns&nbsp;a&nbsp;double&nbsp;result.<br>\n&nbsp;<br>\nThis&nbsp;server&nbsp;does&nbsp;NOT&nbsp;support&nbsp;system.methodSignature.</tt></dd></dl>"""
137+
in response.read())
138+
139+
def test_autolink_dotted_methods(self):
140+
"""Test that selfdot values are made strong automatically in the
141+
documentation."""
142+
self.client.request("GET", "/")
143+
response = self.client.getresponse()
144+
145+
self.assert_("""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""" in
146+
response.read())
147+
148+
def test_main():
149+
test_support.run_unittest(DocXMLRPCHTTPGETServer)
150+
151+
if __name__ == '__main__':
152+
test_main()

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ Zack Weinberg
699699
Edward Welbourne
700700
Cliff Wells
701701
Rickard Westman
702+
Jeff Wheeler
702703
Mats Wichmann
703704
Truida Wiedijk
704705
Felix Wiemann

PC/msvcrtmodule.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ msvcrt_getch(PyObject *self, PyObject *args)
145145
return PyString_FromStringAndSize(s, 1);
146146
}
147147

148+
static PyObject *
149+
msvcrt_getwch(PyObject *self, PyObject *args)
150+
{
151+
Py_UNICODE ch;
152+
Py_UNICODE u[1];
153+
154+
if (!PyArg_ParseTuple(args, ":getwch"))
155+
return NULL;
156+
157+
Py_BEGIN_ALLOW_THREADS
158+
ch = _getwch();
159+
Py_END_ALLOW_THREADS
160+
u[0] = ch;
161+
return PyUnicode_FromUnicode(u, 1);
162+
}
163+
148164
static PyObject *
149165
msvcrt_getche(PyObject *self, PyObject *args)
150166
{
@@ -161,6 +177,22 @@ msvcrt_getche(PyObject *self, PyObject *args)
161177
return PyString_FromStringAndSize(s, 1);
162178
}
163179

180+
static PyObject *
181+
msvcrt_getwche(PyObject *self, PyObject *args)
182+
{
183+
Py_UNICODE ch;
184+
Py_UNICODE s[1];
185+
186+
if (!PyArg_ParseTuple(args, ":getwche"))
187+
return NULL;
188+
189+
Py_BEGIN_ALLOW_THREADS
190+
ch = _getwche();
191+
Py_END_ALLOW_THREADS
192+
s[0] = ch;
193+
return PyUnicode_FromUnicode(s, 1);
194+
}
195+
164196
static PyObject *
165197
msvcrt_putch(PyObject *self, PyObject *args)
166198
{
@@ -174,6 +206,26 @@ msvcrt_putch(PyObject *self, PyObject *args)
174206
return Py_None;
175207
}
176208

209+
210+
static PyObject *
211+
msvcrt_putwch(PyObject *self, PyObject *args)
212+
{
213+
Py_UNICODE *ch;
214+
int size;
215+
216+
if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
217+
return NULL;
218+
219+
if (size == 0) {
220+
PyErr_SetString(PyExc_ValueError,
221+
"Expected unicode string of length 1");
222+
return NULL;
223+
}
224+
_putwch(*ch);
225+
Py_RETURN_NONE;
226+
227+
}
228+
177229
static PyObject *
178230
msvcrt_ungetch(PyObject *self, PyObject *args)
179231
{
@@ -188,6 +240,19 @@ msvcrt_ungetch(PyObject *self, PyObject *args)
188240
return Py_None;
189241
}
190242

243+
static PyObject *
244+
msvcrt_ungetwch(PyObject *self, PyObject *args)
245+
{
246+
Py_UNICODE ch;
247+
248+
if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
249+
return NULL;
250+
251+
if (_ungetch(ch) == EOF)
252+
return PyErr_SetFromErrno(PyExc_IOError);
253+
Py_INCREF(Py_None);
254+
return Py_None;
255+
}
191256

192257
static void
193258
insertint(PyObject *d, char *name, int value)
@@ -276,6 +341,10 @@ static struct PyMethodDef msvcrt_functions[] = {
276341
{"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS},
277342
{"set_error_mode", msvcrt_seterrormode, METH_VARARGS},
278343
#endif
344+
{"getwch", msvcrt_getwch, METH_VARARGS},
345+
{"getwche", msvcrt_getwche, METH_VARARGS},
346+
{"putwch", msvcrt_putwch, METH_VARARGS},
347+
{"ungetwch", msvcrt_ungetwch, METH_VARARGS},
279348
{NULL, NULL}
280349
};
281350

0 commit comments

Comments
 (0)