Merged revisions 59441-59449 via svnmerge from

svn+ssh://pythondev@svn.python.org/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 ...
........
This commit is contained in:
Christian Heimes 2007-12-10 16:18:49 +00:00
parent 0ded5b54bb
commit 2f1019e752
5 changed files with 258 additions and 28 deletions

View file

@ -16,6 +16,10 @@ this in the implementation of the :func:`getpass` function.
Further documentation on these functions can be found in the Platform API
documentation.
The module implements both the normal and wide char variants of the console I/O
api. The normal API deals only with ASCII characters and is of limited use
for internationalized applications. The wide char API should be used where
ever possible
.. _msvcrt-files:
@ -94,6 +98,13 @@ Console I/O
return the keycode. The :kbd:`Control-C` keypress cannot be read with this
function.
.. function:: getwch()
Wide char variant of `func:getch`, returns unicode.
..versionadded:: 2.6
.. function:: getche()
@ -101,16 +112,37 @@ Console I/O
printable character.
.. function:: getwche()
Wide char variant of `func:getche`, returns unicode.
..versionadded:: 2.6
.. function:: putch(char)
Print the character *char* to the console without buffering.
.. function:: putwch(unicode_char)
Wide char variant of `func:putch`, accepts unicode.
..versionadded:: 2.6
.. function:: ungetch(char)
Cause the character *char* to be "pushed back" into the console buffer; it will
be the next character read by :func:`getch` or :func:`getche`.
.. function:: ungetwch(unicode_char)
Wide char variant of `func:ungetch`, accepts unicode.
..versionadded:: 2.6
.. _msvcrt-other:

View file

@ -64,14 +64,15 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
results.append(escape(text[here:]))
return ''.join(results)
def docroutine(self, object, name=None, mod=None,
def docroutine(self, object, name, mod=None,
funcs={}, classes={}, methods={}, cl=None):
"""Produce HTML documentation for a function or method object."""
anchor = (cl and cl.__name__ or '') + '-' + name
note = ''
title = '<a name="%s"><strong>%s</strong></a>' % (anchor, name)
title = '<a name="%s"><strong>%s</strong></a>' % (
self.escape(anchor), self.escape(name))
if inspect.ismethod(object):
args, varargs, varkw, defaults = inspect.getargspec(object)
@ -113,6 +114,7 @@ def docserver(self, server_name, package_documentation, methods):
fdict[key] = '#-' + key
fdict[value] = fdict[key]
server_name = self.escape(server_name)
head = '<big><big><strong>%s</strong></big></big>' % server_name
result = self.heading(head, '#ffffff', '#7799ee')
@ -280,29 +282,3 @@ def handle_get(self):
def __init__(self):
CGIXMLRPCRequestHandler.__init__(self)
XMLRPCDocGenerator.__init__(self)
if __name__ == '__main__':
def deg_to_rad(deg):
"""deg_to_rad(90) => 1.5707963267948966
Converts an angle in degrees to an angle in radians"""
import math
return deg * math.pi / 180
server = DocXMLRPCServer(("localhost", 8000))
server.set_server_title("Math Server")
server.set_server_name("Math XML-RPC Server")
server.set_server_documentation("""This server supports various mathematical functions.
You can use it from Python as follows:
>>> from xmlrpclib import ServerProxy
>>> s = ServerProxy("http://localhost:8000")
>>> s.deg_to_rad(90.0)
1.5707963267948966""")
server.register_function(deg_to_rad)
server.register_introspection_functions()
server.serve_forever()

152
Lib/test/test_docxmlrpc.py Normal file
View file

@ -0,0 +1,152 @@
from DocXMLRPCServer import DocXMLRPCServer
import httplib
from test import test_support
import threading
import time
import unittest
import xmlrpclib
PORT = None
def server(evt, numrequests):
try:
serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
global PORT
PORT = serv.socket.getsockname()[1]
# Add some documentation
serv.set_server_title("DocXMLRPCServer Test Documentation")
serv.set_server_name("DocXMLRPCServer Test Docs")
serv.set_server_documentation(
"""This is an XML-RPC server's documentation, but the server can be used by
POSTing to /RPC2. Try self.add, too.""")
# Create and register classes and functions
class TestClass(object):
def test_method(self, arg):
"""Test method's docs. This method truly does very little."""
self.arg = arg
serv.register_introspection_functions()
serv.register_instance(TestClass())
def add(x, y):
"""Add two instances together. This follows PEP008, but has nothing
to do with RFC1952. Case should matter: pEp008 and rFC1952. Things
that start with http and ftp should be auto-linked, too:
http://google.com.
"""
return x + y
serv.register_function(add)
serv.register_function(lambda x, y: x-y)
while numrequests > 0:
serv.handle_request()
numrequests -= 1
except socket.timeout:
pass
finally:
serv.server_close()
PORT = None
evt.set()
class DocXMLRPCHTTPGETServer(unittest.TestCase):
def setUp(self):
# Enable server feedback
DocXMLRPCServer._send_traceback_header = True
self.evt = threading.Event()
threading.Thread(target=server, args=(self.evt, 1)).start()
# wait for port to be assigned
n = 1000
while n > 0 and PORT is None:
time.sleep(0.001)
n -= 1
self.client = httplib.HTTPConnection("localhost:%d" % PORT)
def tearDown(self):
self.client.close()
self.evt.wait()
# Disable server feedback
DocXMLRPCServer._send_traceback_header = False
def test_valid_get_response(self):
self.client.request("GET", "/")
response = self.client.getresponse()
self.assertEqual(response.status, 200)
self.assertEqual(response.getheader("Content-type"), "text/html")
# Server throws an exception if we don't start to read the data
response.read()
def test_invalid_get_response(self):
self.client.request("GET", "/spam")
response = self.client.getresponse()
self.assertEqual(response.status, 404)
self.assertEqual(response.getheader("Content-type"), "text/plain")
response.read()
def test_lambda(self):
"""Test that lambda functionality stays the same. The output produced
currently is, I suspect invalid because of the unencoded brackets in the
HTML, "<lambda>".
The subtraction lambda method is tested.
"""
self.client.request("GET", "/")
response = self.client.getresponse()
self.assert_(
"""<dl><dt><a name="-&lt;lambda&gt;"><strong>&lt;lambda&gt;</strong></a>(x, y)</dt></dl>"""
in response.read())
def test_autolinking(self):
"""Test that the server correctly automatically wraps references to PEPS
and RFCs with links, and that it linkifies text starting with http or
ftp protocol prefixes.
The documentation for the "add" method contains the test material.
"""
self.client.request("GET", "/")
response = self.client.getresponse()
self.assert_( # This is ugly ... how can it be made better?
"""<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>"""
in response.read())
def test_system_methods(self):
"""Test the precense of three consecutive system.* methods.
This also tests their use of parameter type recognition and the systems
related to that process.
"""
self.client.request("GET", "/")
response = self.client.getresponse()
self.assert_(
"""<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>"""
in response.read())
def test_autolink_dotted_methods(self):
"""Test that selfdot values are made strong automatically in the
documentation."""
self.client.request("GET", "/")
response = self.client.getresponse()
self.assert_("""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""" in
response.read())
def test_main():
test_support.run_unittest(DocXMLRPCHTTPGETServer)
if __name__ == '__main__':
test_main()

View file

@ -699,6 +699,7 @@ Zack Weinberg
Edward Welbourne
Cliff Wells
Rickard Westman
Jeff Wheeler
Mats Wichmann
Truida Wiedijk
Felix Wiemann

View file

@ -145,6 +145,22 @@ msvcrt_getch(PyObject *self, PyObject *args)
return PyString_FromStringAndSize(s, 1);
}
static PyObject *
msvcrt_getwch(PyObject *self, PyObject *args)
{
Py_UNICODE ch;
Py_UNICODE u[1];
if (!PyArg_ParseTuple(args, ":getwch"))
return NULL;
Py_BEGIN_ALLOW_THREADS
ch = _getwch();
Py_END_ALLOW_THREADS
u[0] = ch;
return PyUnicode_FromUnicode(u, 1);
}
static PyObject *
msvcrt_getche(PyObject *self, PyObject *args)
{
@ -161,6 +177,22 @@ msvcrt_getche(PyObject *self, PyObject *args)
return PyString_FromStringAndSize(s, 1);
}
static PyObject *
msvcrt_getwche(PyObject *self, PyObject *args)
{
Py_UNICODE ch;
Py_UNICODE s[1];
if (!PyArg_ParseTuple(args, ":getwche"))
return NULL;
Py_BEGIN_ALLOW_THREADS
ch = _getwche();
Py_END_ALLOW_THREADS
s[0] = ch;
return PyUnicode_FromUnicode(s, 1);
}
static PyObject *
msvcrt_putch(PyObject *self, PyObject *args)
{
@ -174,6 +206,26 @@ msvcrt_putch(PyObject *self, PyObject *args)
return Py_None;
}
static PyObject *
msvcrt_putwch(PyObject *self, PyObject *args)
{
Py_UNICODE *ch;
int size;
if (!PyArg_ParseTuple(args, "u#:putwch", &ch, &size))
return NULL;
if (size == 0) {
PyErr_SetString(PyExc_ValueError,
"Expected unicode string of length 1");
return NULL;
}
_putwch(*ch);
Py_RETURN_NONE;
}
static PyObject *
msvcrt_ungetch(PyObject *self, PyObject *args)
{
@ -188,6 +240,19 @@ msvcrt_ungetch(PyObject *self, PyObject *args)
return Py_None;
}
static PyObject *
msvcrt_ungetwch(PyObject *self, PyObject *args)
{
Py_UNICODE ch;
if (!PyArg_ParseTuple(args, "u:ungetwch", &ch))
return NULL;
if (_ungetch(ch) == EOF)
return PyErr_SetFromErrno(PyExc_IOError);
Py_INCREF(Py_None);
return Py_None;
}
static void
insertint(PyObject *d, char *name, int value)
@ -276,6 +341,10 @@ static struct PyMethodDef msvcrt_functions[] = {
{"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS},
{"set_error_mode", msvcrt_seterrormode, METH_VARARGS},
#endif
{"getwch", msvcrt_getwch, METH_VARARGS},
{"getwche", msvcrt_getwche, METH_VARARGS},
{"putwch", msvcrt_putwch, METH_VARARGS},
{"ungetwch", msvcrt_ungetwch, METH_VARARGS},
{NULL, NULL}
};