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:
parent
0ded5b54bb
commit
2f1019e752
|
@ -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:
|
||||
|
||||
|
|
|
@ -64,14 +64,15 @@ class ServerHTMLDoc(pydoc.HTMLDoc):
|
|||
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 @@ class ServerHTMLDoc(pydoc.HTMLDoc):
|
|||
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 @@ class DocCGIXMLRPCRequestHandler( CGIXMLRPCRequestHandler,
|
|||
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()
|
||||
|
|
|
@ -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="-<lambda>"><strong><lambda></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 two instances together. This follows <a href="http://www.python.org/peps/pep-0008.html">PEP008</a>, but has nothing<br>\nto do with <a href="http://www.rfc-editor.org/rfc/rfc1952.txt">RFC1952</a>. Case should matter: pEp008 and rFC1952. Things<br>\nthat start with http and ftp should be auto-linked, 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>() => [\'add\', \'subtract\', \'multiple\']<br>\n <br>\nReturns a list of the methods supported by the 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\') => "Adds two integers together"<br>\n <br>\nReturns a string containing documentation for the specified 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\') => [double, int, int]<br>\n <br>\nReturns a list describing the signature of the method. In the<br>\nabove example, the add method takes two integers as arguments<br>\nand returns a double result.<br>\n <br>\nThis server does NOT support 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 self.<strong>add</strong>, too.""" in
|
||||
response.read())
|
||||
|
||||
def test_main():
|
||||
test_support.run_unittest(DocXMLRPCHTTPGETServer)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_main()
|
|
@ -699,6 +699,7 @@ Zack Weinberg
|
|||
Edward Welbourne
|
||||
Cliff Wells
|
||||
Rickard Westman
|
||||
Jeff Wheeler
|
||||
Mats Wichmann
|
||||
Truida Wiedijk
|
||||
Felix Wiemann
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue