summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/BaseHTTPServer.py8
-rw-r--r--Lib/CGIHTTPServer.py6
-rw-r--r--Lib/SimpleHTTPServer.py32
-rw-r--r--Lib/distutils/tests/test_build_ext.py72
-rw-r--r--Lib/gzip.py2
-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
-rw-r--r--Lib/tkinter/__init__.py3
-rw-r--r--Lib/zipfile.py13
17 files changed, 862 insertions, 65 deletions
diff --git a/Lib/BaseHTTPServer.py b/Lib/BaseHTTPServer.py
index 8a099fe..7fbbcf2 100644
--- a/Lib/BaseHTTPServer.py
+++ b/Lib/BaseHTTPServer.py
@@ -222,6 +222,12 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
error_message_format = DEFAULT_ERROR_MESSAGE
error_content_type = DEFAULT_ERROR_CONTENT_TYPE
+ # The default request version. This only affects responses up until
+ # the point where the request line is parsed, so it mainly decides what
+ # the client gets back when sending a malformed request line.
+ # Most web servers default to HTTP 0.9, i.e. don't send a status line.
+ default_request_version = "HTTP/0.9"
+
def parse_request(self):
"""Parse a request (internal).
@@ -234,7 +240,7 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
"""
self.command = None # set in case of error on the first line
- self.request_version = version = "HTTP/0.9" # Default
+ self.request_version = version = self.default_request_version
self.close_connection = 1
requestline = str(self.raw_requestline, 'iso-8859-1')
if requestline[-2:] == '\r\n':
diff --git a/Lib/CGIHTTPServer.py b/Lib/CGIHTTPServer.py
index 828b092..29d701a 100644
--- a/Lib/CGIHTTPServer.py
+++ b/Lib/CGIHTTPServer.py
@@ -182,8 +182,10 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
env['AUTH_TYPE'] = authorization[0]
if authorization[0].lower() == "basic":
try:
- authorization = base64.decodestring(authorization[1])
- except binascii.Error:
+ authorization = authorization[1].encode('ascii')
+ authorization = base64.decodestring(authorization).\
+ decode('ascii')
+ except (binascii.Error, UnicodeError):
pass
else:
authorization = authorization.split(':')
diff --git a/Lib/SimpleHTTPServer.py b/Lib/SimpleHTTPServer.py
index beb0a39..36a249c 100644
--- a/Lib/SimpleHTTPServer.py
+++ b/Lib/SimpleHTTPServer.py
@@ -11,13 +11,14 @@ __version__ = "0.6"
__all__ = ["SimpleHTTPRequestHandler"]
import os
+import sys
import posixpath
import BaseHTTPServer
import urllib
import cgi
import shutil
import mimetypes
-from io import StringIO
+from io import BytesIO
class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
@@ -76,12 +77,8 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
else:
return self.list_directory(path)
ctype = self.guess_type(path)
- if ctype.startswith('text/'):
- mode = 'r'
- else:
- mode = 'rb'
try:
- f = open(path, mode)
+ f = open(path, 'rb')
except IOError:
self.send_error(404, "File not found")
return None
@@ -107,12 +104,12 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
self.send_error(404, "No permission to list directory")
return None
list.sort(key=lambda a: a.lower())
- f = StringIO()
+ r = []
displaypath = cgi.escape(urllib.unquote(self.path))
- f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
- f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
- f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
- f.write("<hr>\n<ul>\n")
+ r.append('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
+ r.append("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
+ r.append("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
+ r.append("<hr>\n<ul>\n")
for name in list:
fullname = os.path.join(path, name)
displayname = linkname = name
@@ -123,14 +120,17 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
if os.path.islink(fullname):
displayname = name + "@"
# Note: a link to a directory displays with @ and links with /
- f.write('<li><a href="%s">%s</a>\n'
+ r.append('<li><a href="%s">%s</a>\n'
% (urllib.quote(linkname), cgi.escape(displayname)))
- f.write("</ul>\n<hr>\n</body>\n</html>\n")
- length = f.tell()
+ r.append("</ul>\n<hr>\n</body>\n</html>\n")
+ enc = sys.getfilesystemencoding()
+ encoded = ''.join(r).encode(enc)
+ f = BytesIO()
+ f.write(encoded)
f.seek(0)
self.send_response(200)
- self.send_header("Content-type", "text/html")
- self.send_header("Content-Length", str(length))
+ self.send_header("Content-type", "text/html; charset=%s" % enc)
+ self.send_header("Content-Length", str(len(encoded)))
self.end_headers()
return f
diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py
new file mode 100644
index 0000000..96c0a23
--- /dev/null
+++ b/Lib/distutils/tests/test_build_ext.py
@@ -0,0 +1,72 @@
+import sys
+import os
+import tempfile
+import shutil
+from io import StringIO
+
+from distutils.core import Extension, Distribution
+from distutils.command.build_ext import build_ext
+from distutils import sysconfig
+
+import unittest
+from test import support
+
+class BuildExtTestCase(unittest.TestCase):
+ def setUp(self):
+ # Create a simple test environment
+ # Note that we're making changes to sys.path
+ self.tmp_dir = tempfile.mkdtemp(prefix="pythontest_")
+ self.sys_path = sys.path[:]
+ sys.path.append(self.tmp_dir)
+
+ xx_c = os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c')
+ shutil.copy(xx_c, self.tmp_dir)
+
+ def test_build_ext(self):
+ xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
+ xx_ext = Extension('xx', [xx_c])
+ dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})
+ dist.package_dir = self.tmp_dir
+ cmd = build_ext(dist)
+ cmd.build_lib = self.tmp_dir
+ cmd.build_temp = self.tmp_dir
+
+ old_stdout = sys.stdout
+ if not support.verbose:
+ # silence compiler output
+ sys.stdout = StringIO()
+ try:
+ cmd.ensure_finalized()
+ cmd.run()
+ finally:
+ sys.stdout = old_stdout
+
+ import xx
+
+ for attr in ('error', 'foo', 'new', 'roj'):
+ self.assert_(hasattr(xx, attr))
+
+ self.assertEquals(xx.foo(2, 5), 7)
+ self.assertEquals(xx.foo(13,15), 28)
+ self.assertEquals(xx.new().demo(), None)
+ doc = 'This is a template module just for instruction.'
+ self.assertEquals(xx.__doc__, doc)
+ self.assert_(isinstance(xx.Null(), xx.Null))
+ self.assert_(isinstance(xx.Str(), xx.Str))
+
+ def tearDown(self):
+ # Get everything back to normal
+ support.unload('xx')
+ sys.path = self.sys_path
+ # XXX on Windows the test leaves a directory with xx.pyd in TEMP
+ shutil.rmtree(self.tmp_dir, False if os.name != "nt" else True)
+
+def test_suite():
+ if not sysconfig.python_build:
+ if support.verbose:
+ print('test_build_ext: The test must be run in a python build dir')
+ return unittest.TestSuite()
+ else: return unittest.makeSuite(BuildExtTestCase)
+
+if __name__ == '__main__':
+ support.run_unittest(test_suite())
diff --git a/Lib/gzip.py b/Lib/gzip.py
index 45fae9f..9d8dac5 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -323,6 +323,8 @@ class GzipFile:
raise IOError("Incorrect length of data produced")
def close(self):
+ if self.fileobj is None:
+ return
if self.mode == WRITE:
self.fileobj.write(self.compress.flush())
write32u(self.fileobj, self.crc)
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)
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index 49ca8a5..f26fda9 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -2903,8 +2903,7 @@ class Text(Widget):
and edit_undo
"""
- return self._getints(
- self.tk.call((self._w, 'edit') + args)) or ()
+ return self.tk.call(self._w, 'edit', *args)
def edit_modified(self, arg=None):
"""Get or Set the modified flag
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 73b62af..fd923c8 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -783,10 +783,13 @@ class ZipFile:
else:
zef_file = io.open(self.filename, 'rb')
- # Get info object for name
- zinfo = self.getinfo(name)
-
- filepos = zef_file.tell()
+ # Make sure we have an info object
+ if isinstance(name, ZipInfo):
+ # 'name' is already an info object
+ zinfo = name
+ else:
+ # Get info object for name
+ zinfo = self.getinfo(name)
zef_file.seek(zinfo.header_offset, 0)
@@ -891,7 +894,7 @@ class ZipFile:
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
- source = self.open(member.filename, pwd=pwd)
+ source = self.open(member, pwd=pwd)
target = open(targetpath, "wb")
shutil.copyfileobj(source, target)
source.close()