summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2008-05-25 18:19:30 (GMT)
committerGeorg Brandl <georg@python.org>2008-05-25 18:19:30 (GMT)
commitb533e26dfae98f00facb50a6d3d6c200771d051f (patch)
treec41061c14b853728742903222b936b9614ff1d93 /Lib/test
parentcea777423b67a5ea1ed104b217373556d6ff0383 (diff)
downloadcpython-b533e26dfae98f00facb50a6d3d6c200771d051f.zip
cpython-b533e26dfae98f00facb50a6d3d6c200771d051f.tar.gz
cpython-b533e26dfae98f00facb50a6d3d6c200771d051f.tar.bz2
Merged revisions 63412,63445-63447,63449-63450,63452,63454,63459,63463,63465,63470,63483-63484,63496-63497,63499-63501,63530-63531,63540,63614 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r63412 | georg.brandl | 2008-05-17 19:57:01 +0200 (Sat, 17 May 2008) | 2 lines #961805: fix Edit.text_modified(). ........ r63445 | georg.brandl | 2008-05-18 10:52:59 +0200 (Sun, 18 May 2008) | 2 lines GHOP #180 by Michael Schneider: add examples to the socketserver documentation. ........ r63446 | georg.brandl | 2008-05-18 11:12:20 +0200 (Sun, 18 May 2008) | 2 lines GHOP #134, #171, #137: unit tests for the three HTTPServer modules. ........ r63447 | georg.brandl | 2008-05-18 12:39:26 +0200 (Sun, 18 May 2008) | 3 lines Take namedtuple item names only from ascii_letters (this blew up on OSX), and make sure there are no duplicate names. ........ r63449 | georg.brandl | 2008-05-18 13:46:51 +0200 (Sun, 18 May 2008) | 2 lines GHOP #217: add support for compiling Python with coverage checking enabled. ........ r63450 | georg.brandl | 2008-05-18 13:52:36 +0200 (Sun, 18 May 2008) | 2 lines GHOP #257: test distutils' build_ext command, written by Josip Dzolonga. ........ r63452 | georg.brandl | 2008-05-18 15:34:06 +0200 (Sun, 18 May 2008) | 2 lines Add GHOP students. ........ r63454 | georg.brandl | 2008-05-18 18:32:48 +0200 (Sun, 18 May 2008) | 2 lines GHOP #121: improve test_pydoc, by Benjamin Peterson. ........ r63459 | benjamin.peterson | 2008-05-18 22:48:07 +0200 (Sun, 18 May 2008) | 2 lines bring test_pydoc up to my high standards (now that I have them) ........ r63463 | georg.brandl | 2008-05-18 23:10:19 +0200 (Sun, 18 May 2008) | 2 lines Fix test_pyclbr after another platform-dependent function was added to urllib. ........ r63465 | benjamin.peterson | 2008-05-19 01:07:07 +0200 (Mon, 19 May 2008) | 2 lines change some imports in tests so they will not be skipped in 3.0 ........ r63470 | georg.brandl | 2008-05-19 18:47:25 +0200 (Mon, 19 May 2008) | 2 lines test_httpservers has unpredictable refcount behavior. ........ r63483 | georg.brandl | 2008-05-20 08:15:36 +0200 (Tue, 20 May 2008) | 2 lines Activate two more test cases in test_httpservers. ........ r63484 | georg.brandl | 2008-05-20 08:47:31 +0200 (Tue, 20 May 2008) | 2 lines Argh, this is the *actual* test that works under Windows. ........ r63496 | georg.brandl | 2008-05-20 10:07:36 +0200 (Tue, 20 May 2008) | 2 lines Improve diffing logic and output for test_pydoc. ........ r63497 | georg.brandl | 2008-05-20 10:10:03 +0200 (Tue, 20 May 2008) | 2 lines Use inspect.getabsfile() to get the documented module's filename. ........ r63499 | georg.brandl | 2008-05-20 10:25:48 +0200 (Tue, 20 May 2008) | 3 lines Patch #1775025: allow opening zipfile members via ZipInfo instances. Patch by Graham Horler. ........ r63500 | georg.brandl | 2008-05-20 10:40:43 +0200 (Tue, 20 May 2008) | 2 lines #2592: delegate nb_index and the floor/truediv slots in weakref.proxy. ........ r63501 | georg.brandl | 2008-05-20 10:48:34 +0200 (Tue, 20 May 2008) | 2 lines #615772: raise a more explicit error from Tkinter.Misc.__contains__. ........ r63530 | benjamin.peterson | 2008-05-22 02:57:02 +0200 (Thu, 22 May 2008) | 2 lines use more specific asserts in test_opcode ........ r63531 | benjamin.peterson | 2008-05-22 03:02:23 +0200 (Thu, 22 May 2008) | 2 lines remove redundant invocation of json doctests ........ r63540 | benjamin.peterson | 2008-05-23 01:09:26 +0200 (Fri, 23 May 2008) | 3 lines fix test_pydoc so it works on make installed Python installations Also let it pass when invoked directly ........ r63614 | georg.brandl | 2008-05-25 10:07:37 +0200 (Sun, 25 May 2008) | 2 lines #2959: allow multiple close() calls for GzipFile. ........
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/pydoc_mod.py54
-rw-r--r--Lib/test/test_collections.py4
-rw-r--r--Lib/test/test_gzip.py9
-rw-r--r--Lib/test/test_httpservers.py354
-rw-r--r--Lib/test/test_json.py1
-rw-r--r--Lib/test/test_opcodes.py16
-rw-r--r--Lib/test/test_pyclbr.py1
-rw-r--r--Lib/test/test_pydoc.py310
-rw-r--r--Lib/test/test_weakref.py23
-rw-r--r--Lib/test/test_zipfile.py19
10 files changed, 752 insertions, 39 deletions
diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py
new file mode 100644
index 0000000..8601e3f
--- /dev/null
+++ b/Lib/test/pydoc_mod.py
@@ -0,0 +1,54 @@
+"""This is a test module for test_pydoc"""
+
+__author__ = "Benjamin Peterson"
+__credits__ = "Nobody"
+__version__ = "1.2.3.4"
+
+
+class A:
+ """Hello and goodbye"""
+ def __init__():
+ """Wow, I have no function!"""
+ pass
+
+class B(object):
+ NO_MEANING = "eggs"
+ pass
+
+def doc_func():
+ """
+ This function solves all of the world's problems:
+ hunger
+ lack of Python
+ war
+ """
+
+def nodoc_func():
+ pass
+"""This is a test module for test_pydoc"""
+
+__author__ = "Benjamin Peterson"
+__credits__ = "Nobody"
+__version__ = "1.2.3.4"
+
+
+class A:
+ """Hello and goodbye"""
+ def __init__():
+ """Wow, I have no function!"""
+ pass
+
+class B(object):
+ NO_MEANING = "eggs"
+ pass
+
+def doc_func():
+ """
+ This function solves all of the world's problems:
+ hunger
+ lack of Python
+ war
+ """
+
+def nodoc_func():
+ pass
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index ad8c230..4ed0e24 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -114,7 +114,9 @@ class TestNamedTuple(unittest.TestCase):
# n = 10000
n = 254 # SyntaxError: more than 255 arguments:
import string, random
- names = [''.join([random.choice(string.ascii_letters) for j in range(10)]) for i in range(n)]
+ names = list(set(''.join([random.choice(string.ascii_letters)
+ for j in range(10)]) for i in range(n)))
+ n = len(names)
Big = namedtuple('Big', names)
b = Big(*range(n))
self.assertEqual(b, tuple(range(n)))
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index c26035b..d28c024 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -24,14 +24,14 @@ data2 = b"""/* zlibmodule.c -- gzip-compatible data compression */
class TestGzip(unittest.TestCase):
filename = support.TESTFN
- def setUp (self):
+ def setUp(self):
support.unlink(self.filename)
- def tearDown (self):
+ def tearDown(self):
support.unlink(self.filename)
- def test_write (self):
+ def test_write(self):
f = gzip.GzipFile(self.filename, 'wb') ; f.write(data1 * 50)
# Try flush and fileno.
@@ -41,6 +41,9 @@ class TestGzip(unittest.TestCase):
os.fsync(f.fileno())
f.close()
+ # Test multiple close() calls.
+ f.close()
+
def test_read(self):
self.test_write()
# Try reading.
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
new file mode 100644
index 0000000..cc79cb8
--- /dev/null
+++ b/Lib/test/test_httpservers.py
@@ -0,0 +1,354 @@
+"""Unittests for the various HTTPServer modules.
+
+Written by Cody A.W. Somerville <cody-somerville@ubuntu.com>,
+Josip Dzolonga, and Michael Otteneder for the 2007/08 GHOP contest.
+"""
+
+from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+from SimpleHTTPServer import SimpleHTTPRequestHandler
+from CGIHTTPServer import CGIHTTPRequestHandler
+
+import os
+import sys
+import base64
+import shutil
+import urllib
+import httplib
+import tempfile
+import threading
+
+import unittest
+from test import support
+
+
+class NoLogRequestHandler:
+ def log_message(self, *args):
+ # don't write log messages to stderr
+ pass
+
+
+class TestServerThread(threading.Thread):
+ def __init__(self, test_object, request_handler):
+ threading.Thread.__init__(self)
+ self.request_handler = request_handler
+ self.test_object = test_object
+ self.test_object.lock.acquire()
+
+ def run(self):
+ self.server = HTTPServer(('', 0), self.request_handler)
+ self.test_object.PORT = self.server.socket.getsockname()[1]
+ self.test_object.lock.release()
+ try:
+ self.server.serve_forever()
+ finally:
+ self.server.server_close()
+
+ def stop(self):
+ self.server.shutdown()
+
+
+class BaseTestCase(unittest.TestCase):
+ def setUp(self):
+ self.lock = threading.Lock()
+ self.thread = TestServerThread(self, self.request_handler)
+ self.thread.start()
+ self.lock.acquire()
+
+ def tearDown(self):
+ self.lock.release()
+ self.thread.stop()
+
+ def request(self, uri, method='GET', body=None, headers={}):
+ self.connection = httplib.HTTPConnection('localhost', self.PORT)
+ self.connection.request(method, uri, body, headers)
+ return self.connection.getresponse()
+
+
+class BaseHTTPServerTestCase(BaseTestCase):
+ class request_handler(NoLogRequestHandler, BaseHTTPRequestHandler):
+ protocol_version = 'HTTP/1.1'
+ default_request_version = 'HTTP/1.1'
+
+ def do_TEST(self):
+ self.send_response(204)
+ self.send_header('Content-Type', 'text/html')
+ self.send_header('Connection', 'close')
+ self.end_headers()
+
+ def do_KEEP(self):
+ self.send_response(204)
+ self.send_header('Content-Type', 'text/html')
+ self.send_header('Connection', 'keep-alive')
+ self.end_headers()
+
+ def do_KEYERROR(self):
+ self.send_error(999)
+
+ def do_CUSTOM(self):
+ self.send_response(999)
+ self.send_header('Content-Type', 'text/html')
+ self.send_header('Connection', 'close')
+ self.end_headers()
+
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.con = httplib.HTTPConnection('localhost', self.PORT)
+ self.con.connect()
+
+ def test_command(self):
+ self.con.request('GET', '/')
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 501)
+
+ def test_request_line_trimming(self):
+ self.con._http_vsn_str = 'HTTP/1.1\n'
+ self.con.putrequest('GET', '/')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 501)
+
+ def test_version_bogus(self):
+ self.con._http_vsn_str = 'FUBAR'
+ self.con.putrequest('GET', '/')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 400)
+
+ def test_version_digits(self):
+ self.con._http_vsn_str = 'HTTP/9.9.9'
+ self.con.putrequest('GET', '/')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 400)
+
+ def test_version_none_get(self):
+ self.con._http_vsn_str = ''
+ self.con.putrequest('GET', '/')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 501)
+
+ def test_version_none(self):
+ self.con._http_vsn_str = ''
+ self.con.putrequest('PUT', '/')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 400)
+
+ def test_version_invalid(self):
+ self.con._http_vsn = 99
+ self.con._http_vsn_str = 'HTTP/9.9'
+ self.con.putrequest('GET', '/')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 505)
+
+ def test_send_blank(self):
+ self.con._http_vsn_str = ''
+ self.con.putrequest('', '')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 400)
+
+ def test_header_close(self):
+ self.con.putrequest('GET', '/')
+ self.con.putheader('Connection', 'close')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 501)
+
+ def test_head_keep_alive(self):
+ self.con._http_vsn_str = 'HTTP/1.1'
+ self.con.putrequest('GET', '/')
+ self.con.putheader('Connection', 'keep-alive')
+ self.con.endheaders()
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 501)
+
+ def test_handler(self):
+ self.con.request('TEST', '/')
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 204)
+
+ def test_return_header_keep_alive(self):
+ self.con.request('KEEP', '/')
+ res = self.con.getresponse()
+ self.assertEquals(res.getheader('Connection'), 'keep-alive')
+ self.con.request('TEST', '/')
+
+ def test_internal_key_error(self):
+ self.con.request('KEYERROR', '/')
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 999)
+
+ def test_return_custom_status(self):
+ self.con.request('CUSTOM', '/')
+ res = self.con.getresponse()
+ self.assertEquals(res.status, 999)
+
+
+class SimpleHTTPServerTestCase(BaseTestCase):
+ class request_handler(NoLogRequestHandler, SimpleHTTPRequestHandler):
+ pass
+
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.cwd = os.getcwd()
+ basetempdir = tempfile.gettempdir()
+ os.chdir(basetempdir)
+ self.data = b'We are the knights who say Ni!'
+ self.tempdir = tempfile.mkdtemp(dir=basetempdir)
+ self.tempdir_name = os.path.basename(self.tempdir)
+ temp = open(os.path.join(self.tempdir, 'test'), 'wb')
+ temp.write(self.data)
+ temp.close()
+
+ def tearDown(self):
+ try:
+ os.chdir(self.cwd)
+ try:
+ shutil.rmtree(self.tempdir)
+ except:
+ pass
+ finally:
+ BaseTestCase.tearDown(self)
+
+ def check_status_and_reason(self, response, status, data=None):
+ body = response.read()
+ self.assert_(response)
+ self.assertEquals(response.status, status)
+ self.assert_(response.reason != None)
+ if data:
+ self.assertEqual(data, body)
+
+ def test_get(self):
+ #constructs the path relative to the root directory of the HTTPServer
+ response = self.request(self.tempdir_name + '/test')
+ self.check_status_and_reason(response, 200, data=self.data)
+ response = self.request(self.tempdir_name + '/')
+ self.check_status_and_reason(response, 200)
+ response = self.request(self.tempdir_name)
+ self.check_status_and_reason(response, 301)
+ response = self.request('/ThisDoesNotExist')
+ self.check_status_and_reason(response, 404)
+ response = self.request('/' + 'ThisDoesNotExist' + '/')
+ self.check_status_and_reason(response, 404)
+ f = open(os.path.join(self.tempdir_name, 'index.html'), 'w')
+ response = self.request('/' + self.tempdir_name + '/')
+ self.check_status_and_reason(response, 200)
+ if os.name == 'posix':
+ # chmod won't work as expected on Windows platforms
+ os.chmod(self.tempdir, 0)
+ response = self.request(self.tempdir_name + '/')
+ self.check_status_and_reason(response, 404)
+ os.chmod(self.tempdir, 0o755)
+
+ def test_head(self):
+ response = self.request(
+ self.tempdir_name + '/test', method='HEAD')
+ self.check_status_and_reason(response, 200)
+ self.assertEqual(response.getheader('content-length'),
+ str(len(self.data)))
+ self.assertEqual(response.getheader('content-type'),
+ 'application/octet-stream')
+
+ def test_invalid_requests(self):
+ response = self.request('/', method='FOO')
+ self.check_status_and_reason(response, 501)
+ # requests must be case sensitive,so this should fail too
+ response = self.request('/', method='get')
+ self.check_status_and_reason(response, 501)
+ response = self.request('/', method='GETs')
+ self.check_status_and_reason(response, 501)
+
+
+cgi_file1 = """\
+#!%s
+
+print("Content-type: text/html")
+print()
+print("Hello World")
+"""
+
+cgi_file2 = """\
+#!%s
+import cgi
+
+print("Content-type: text/html")
+print()
+
+form = cgi.FieldStorage()
+print("%%s, %%s, %%s" %% (form.getfirst("spam"), form.getfirst("eggs"),\
+ form.getfirst("bacon")))
+"""
+
+class CGIHTTPServerTestCase(BaseTestCase):
+ class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler):
+ pass
+
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.parent_dir = tempfile.mkdtemp()
+ self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin')
+ os.mkdir(self.cgi_dir)
+
+ self.file1_path = os.path.join(self.cgi_dir, 'file1.py')
+ with open(self.file1_path, 'w') as file1:
+ file1.write(cgi_file1 % sys.executable)
+ os.chmod(self.file1_path, 0o777)
+
+ self.file2_path = os.path.join(self.cgi_dir, 'file2.py')
+ with open(self.file2_path, 'w') as file2:
+ file2.write(cgi_file2 % sys.executable)
+ os.chmod(self.file2_path, 0o777)
+
+ self.cwd = os.getcwd()
+ os.chdir(self.parent_dir)
+
+ def tearDown(self):
+ try:
+ os.chdir(self.cwd)
+ os.remove(self.file1_path)
+ os.remove(self.file2_path)
+ os.rmdir(self.cgi_dir)
+ os.rmdir(self.parent_dir)
+ finally:
+ BaseTestCase.tearDown(self)
+
+ def test_headers_and_content(self):
+ res = self.request('/cgi-bin/file1.py')
+ self.assertEquals((b'Hello World\n', 'text/html', 200), \
+ (res.read(), res.getheader('Content-type'), res.status))
+
+ def test_post(self):
+ params = urllib.urlencode({'spam' : 1, 'eggs' : 'python', 'bacon' : 123456})
+ headers = {'Content-type' : 'application/x-www-form-urlencoded'}
+ res = self.request('/cgi-bin/file2.py', 'POST', params, headers)
+
+ self.assertEquals(res.read(), b'1, python, 123456\n')
+
+ def test_invaliduri(self):
+ res = self.request('/cgi-bin/invalid')
+ res.read()
+ self.assertEquals(res.status, 404)
+
+ def test_authorization(self):
+ headers = {b'Authorization' : b'Basic ' +
+ base64.b64encode(b'username:pass')}
+ res = self.request('/cgi-bin/file1.py', 'GET', headers=headers)
+ self.assertEquals((b'Hello World\n', 'text/html', 200), \
+ (res.read(), res.getheader('Content-type'), res.status))
+
+
+def test_main(verbose=None):
+ try:
+ cwd = os.getcwd()
+ support.run_unittest(#BaseHTTPServerTestCase,
+ SimpleHTTPServerTestCase,
+ CGIHTTPServerTestCase
+ )
+ finally:
+ os.chdir(cwd)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_json.py b/Lib/test/test_json.py
index 17e1daf..a4b6e7a 100644
--- a/Lib/test/test_json.py
+++ b/Lib/test/test_json.py
@@ -11,7 +11,6 @@ import test.support
def test_main():
test.support.run_unittest(json.tests.test_suite())
- test.support.run_doctest(json)
if __name__ == "__main__":
diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py
index 42ba600..8fe77ac 100644
--- a/Lib/test/test_opcodes.py
+++ b/Lib/test/test_opcodes.py
@@ -68,35 +68,35 @@ class OpcodeTest(unittest.TestCase):
f = eval('lambda: None')
g = eval('lambda: None')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda a: a')
g = eval('lambda a: a')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda a=1: a')
g = eval('lambda a=1: a')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda: 0')
g = eval('lambda: 1')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda: None')
g = eval('lambda a: None')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda a: None')
g = eval('lambda b: None')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda a: None')
g = eval('lambda a=None: None')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
f = eval('lambda a=0: None')
g = eval('lambda a=1: None')
- self.failIf(f == g)
+ self.assertNotEquals(f, g)
def test_main():
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index bcc16df..ca0aefc 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -158,6 +158,7 @@ class PyclbrTest(TestCase):
cm('cgi', ignore=('log',)) # set with = in module
cm('urllib', ignore=('_CFNumberToInt32',
'_CStringFromCFString',
+ '_CFSetup',
'getproxies_registry',
'proxy_bypass_registry',
'proxy_bypass_macosx_sysconf',
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index cc4a096..ab1b083 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1,25 +1,285 @@
-from test import support
-import unittest
-import pydoc
-
-class TestDescriptions(unittest.TestCase):
- def test_module(self):
- # Check that pydocfodder module can be described
- from test import pydocfodder
- doc = pydoc.render_doc(pydocfodder)
- assert "pydocfodder" in doc
-
- def test_class(self):
- class C(object): "New-style class"
- c = C()
-
- self.failUnlessEqual(pydoc.describe(C), 'class C')
- self.failUnlessEqual(pydoc.describe(c), 'C')
- self.failUnless('C in module test.test_pydoc object'
- in pydoc.render_doc(c))
-
-def test_main():
- support.run_unittest(TestDescriptions)
-
-if __name__ == "__main__":
- unittest.main()
+import sys
+import os
+import difflib
+import subprocess
+import re
+import pydoc
+import inspect
+import unittest
+import test.support
+
+from test import pydoc_mod
+
+expected_text_pattern = \
+"""
+NAME
+ test.pydoc_mod - This is a test module for test_pydoc
+
+FILE
+ %s
+%s
+CLASSES
+ builtins.object
+ A
+ B
+\x20\x20\x20\x20
+ class A(builtins.object)
+ | Hello and goodbye
+ |\x20\x20
+ | Methods defined here:
+ |\x20\x20
+ | __init__()
+ | Wow, I have no function!
+ |\x20\x20
+ | ----------------------------------------------------------------------
+ | Data descriptors defined here:
+ |\x20\x20
+ | __dict__
+ | dictionary for instance variables (if defined)
+ |\x20\x20
+ | __weakref__
+ | list of weak references to the object (if defined)
+\x20\x20\x20\x20
+ class B(builtins.object)
+ | Data descriptors defined here:
+ |\x20\x20
+ | __dict__
+ | dictionary for instance variables (if defined)
+ |\x20\x20
+ | __weakref__
+ | list of weak references to the object (if defined)
+ |\x20\x20
+ | ----------------------------------------------------------------------
+ | Data and other attributes defined here:
+ |\x20\x20
+ | NO_MEANING = 'eggs'
+
+FUNCTIONS
+ doc_func()
+ This function solves all of the world's problems:
+ hunger
+ lack of Python
+ war
+\x20\x20\x20\x20
+ nodoc_func()
+
+DATA
+ __author__ = 'Benjamin Peterson'
+ __credits__ = 'Nobody'
+ __package__ = None
+ __version__ = '1.2.3.4'
+
+VERSION
+ 1.2.3.4
+
+AUTHOR
+ Benjamin Peterson
+
+CREDITS
+ Nobody
+""".strip()
+
+expected_html_pattern = \
+"""
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="#7799ee">
+<td valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="test.html"><font color="#ffffff">test</font></a>.pydoc_mod</strong></big></big> (version 1.2.3.4)</font></td
+><td align=right valign=bottom
+><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:%s">%s</a>%s</font></td></tr></table>
+ <p><tt>This&nbsp;is&nbsp;a&nbsp;test&nbsp;module&nbsp;for&nbsp;test_pydoc</tt></p>
+<p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ee77aa">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
+\x20\x20\x20\x20
+<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%%"><dl>
+<dt><font face="helvetica, arial"><a href="builtins.html#object">builtins.object</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="test.pydoc_mod.html#A">A</a>
+</font></dt><dt><font face="helvetica, arial"><a href="test.pydoc_mod.html#B">B</a>
+</font></dt></dl>
+</dd>
+</dl>
+ <p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="A">class <strong>A</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
+\x20\x20\x20\x20
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Hello&nbsp;and&nbsp;goodbye<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%%">Methods defined here:<br>
+<dl><dt><a name="A-__init__"><strong>__init__</strong></a>()</dt><dd><tt>Wow,&nbsp;I&nbsp;have&nbsp;no&nbsp;function!</tt></dd></dl>
+
+<hr>
+Data descriptors defined here:<br>
+<dl><dt><strong>__dict__</strong></dt>
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
+</dl>
+<dl><dt><strong>__weakref__</strong></dt>
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
+</dl>
+</td></tr></table> <p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="B">class <strong>B</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
+\x20\x20\x20\x20
+<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%%">Data descriptors defined here:<br>
+<dl><dt><strong>__dict__</strong></dt>
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
+</dl>
+<dl><dt><strong>__weakref__</strong></dt>
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
+</dl>
+<hr>
+Data and other attributes defined here:<br>
+<dl><dt><strong>NO_MEANING</strong> = 'eggs'</dl>
+
+</td></tr></table></td></tr></table><p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#eeaa77">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
+\x20\x20\x20\x20
+<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%%"><dl><dt><a name="-doc_func"><strong>doc_func</strong></a>()</dt><dd><tt>This&nbsp;function&nbsp;solves&nbsp;all&nbsp;of&nbsp;the&nbsp;world's&nbsp;problems:<br>
+hunger<br>
+lack&nbsp;of&nbsp;Python<br>
+war</tt></dd></dl>
+ <dl><dt><a name="-nodoc_func"><strong>nodoc_func</strong></a>()</dt></dl>
+</td></tr></table><p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#55aa55">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
+\x20\x20\x20\x20
+<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%%"><strong>__author__</strong> = 'Benjamin Peterson'<br>
+<strong>__credits__</strong> = 'Nobody'<br>
+<strong>__package__</strong> = None<br>
+<strong>__version__</strong> = '1.2.3.4'</td></tr></table><p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#7799ee">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Author</strong></big></font></td></tr>
+\x20\x20\x20\x20
+<tr><td bgcolor="#7799ee"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%%">Benjamin&nbsp;Peterson</td></tr></table><p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#7799ee">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Credits</strong></big></font></td></tr>
+\x20\x20\x20\x20
+<tr><td bgcolor="#7799ee"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%%">Nobody</td></tr></table>
+""".strip()
+
+
+# output pattern for missing module
+missing_pattern = "no Python documentation found for '%s'"
+
+def run_pydoc(module_name, *args):
+ """
+ Runs pydoc on the specified module. Returns the stripped
+ output of pydoc.
+ """
+ cmd = [sys.executable, pydoc.__file__, " ".join(args), module_name]
+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout.read()
+ return output.strip()
+
+def get_pydoc_html(module):
+ "Returns pydoc generated output as html"
+ doc = pydoc.HTMLDoc()
+ output = doc.docmodule(module)
+ loc = doc.getdocloc(pydoc_mod) or ""
+ if loc:
+ loc = "<br><a href=\"" + loc + "\">Module Docs</a>"
+ return output.strip(), loc
+
+def get_pydoc_text(module):
+ "Returns pydoc generated output as text"
+ doc = pydoc.TextDoc()
+ loc = doc.getdocloc(pydoc_mod) or ""
+ if loc:
+ loc = "\nMODULE DOCS\n " + loc + "\n"
+
+ output = doc.docmodule(module)
+
+ # cleanup the extra text formatting that pydoc preforms
+ patt = re.compile('\b.')
+ output = patt.sub('', output)
+ return output.strip(), loc
+
+def print_diffs(text1, text2):
+ "Prints unified diffs for two texts"
+ lines1 = text1.splitlines(True)
+ lines2 = text2.splitlines(True)
+ diffs = difflib.unified_diff(lines1, lines2, n=0, fromfile='expected',
+ tofile='got')
+ print('\n' + ''.join(diffs))
+
+
+class PyDocDocTest(unittest.TestCase):
+
+ def test_html_doc(self):
+ result, doc_loc = get_pydoc_html(pydoc_mod)
+ mod_file = inspect.getabsfile(pydoc_mod)
+ expected_html = expected_html_pattern % (mod_file, mod_file, doc_loc)
+ if result != expected_html:
+ print_diffs(expected_html, result)
+ self.fail("outputs are not equal, see diff above")
+
+ def test_text_doc(self):
+ result, doc_loc = get_pydoc_text(pydoc_mod)
+ expected_text = expected_text_pattern % \
+ (inspect.getabsfile(pydoc_mod), doc_loc)
+ if result != expected_text:
+ print_diffs(expected_text, result)
+ self.fail("outputs are not equal, see diff above")
+
+ def test_not_here(self):
+ missing_module = "test.i_am_not_here"
+ result = str(run_pydoc(missing_module), 'ascii')
+ expected = missing_pattern % missing_module
+ self.assertEqual(expected, result,
+ "documentation for missing module found")
+
+
+class TestDescriptions(unittest.TestCase):
+
+ def test_module(self):
+ # Check that pydocfodder module can be described
+ from test import pydocfodder
+ doc = pydoc.render_doc(pydocfodder)
+ self.assert_("pydocfodder" in doc)
+
+ def test_classic_class(self):
+ class C: "Classic class"
+ c = C()
+ self.assertEqual(pydoc.describe(C), 'class C')
+ self.assertEqual(pydoc.describe(c), 'C')
+ expected = 'C in module %s' % __name__
+ self.assert_(expected in pydoc.render_doc(c))
+
+ def test_class(self):
+ class C(object): "New-style class"
+ c = C()
+
+ self.assertEqual(pydoc.describe(C), 'class C')
+ self.assertEqual(pydoc.describe(c), 'C')
+ expected = 'C in module %s object' % __name__
+ self.assert_(expected in pydoc.render_doc(c))
+
+
+def test_main():
+ test.support.run_unittest(PyDocDocTest, TestDescriptions)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 303345b..a056c23 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -3,6 +3,7 @@ import sys
import unittest
import collections
import weakref
+import operator
from test import support
@@ -182,6 +183,26 @@ class ReferencesTestCase(TestBase):
self.assertEqual(L3[:5], p3[:5])
self.assertEqual(L3[2:5], p3[2:5])
+ def test_proxy_index(self):
+ class C:
+ def __index__(self):
+ return 10
+ o = C()
+ p = weakref.proxy(o)
+ self.assertEqual(operator.index(p), 10)
+
+ def test_proxy_div(self):
+ class C:
+ def __floordiv__(self, other):
+ return 42
+ def __ifloordiv__(self, other):
+ return 21
+ o = C()
+ p = weakref.proxy(o)
+ self.assertEqual(p // 5, 42)
+ p //= 5
+ self.assertEqual(p, 21)
+
# The PyWeakref_* C API is documented as allowing either NULL or
# None as the value for the callback, where either means "no
# callback". The "no callback" ref and proxy objects are supposed
@@ -1059,7 +1080,7 @@ class WeakKeyDictionaryTestCase(mapping_tests.BasicTestMappingProtocol):
def _reference(self):
return self.__ref.copy()
-libreftest = """ Doctest for examples in the library reference: libweakref.tex
+libreftest = """ Doctest for examples in the library reference: weakref.rst
>>> import weakref
>>> class Dict(dict):
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index 30efeb9..4682b7d 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -125,6 +125,25 @@ class TestsWithSourceFile(unittest.TestCase):
for f in (TESTFN2, TemporaryFile(), io.BytesIO()):
self.zipOpenTest(f, zipfile.ZIP_STORED)
+ def testOpenViaZipInfo(self):
+ # Create the ZIP archive
+ zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
+ zipfp.writestr("name", "foo")
+ zipfp.writestr("name", "bar")
+ zipfp.close()
+
+ zipfp = zipfile.ZipFile(TESTFN2, "r")
+ infos = zipfp.infolist()
+ data = b""
+ for info in infos:
+ data += zipfp.open(info).read()
+ self.assert_(data == b"foobar" or data == b"barfoo")
+ data = b""
+ for info in infos:
+ data += zipfp.read(info)
+ self.assert_(data == b"foobar" or data == b"barfoo")
+ zipfp.close()
+
def zipRandomOpenTest(self, f, compression):
self.makeTestArchive(f, compression)