summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/MimeWriter.py181
-rw-r--r--Lib/SocketServer.py9
-rw-r--r--Lib/bsddb/test/test_thread.py6
-rw-r--r--Lib/ctypes/wintypes.py4
-rw-r--r--Lib/dis.py14
-rw-r--r--Lib/idlelib/StackViewer.py15
-rw-r--r--Lib/ihooks.py7
-rw-r--r--Lib/imputil.py20
-rw-r--r--Lib/logging/__init__.py2
-rw-r--r--Lib/logging/handlers.py3
-rwxr-xr-xLib/mimify.py464
-rw-r--r--Lib/optparse.py6
-rw-r--r--Lib/os.py5
-rw-r--r--Lib/plat-mac/buildtools.py3
-rw-r--r--Lib/plat-mac/cfmfile.py183
-rw-r--r--Lib/posixfile.py237
-rwxr-xr-xLib/pydoc.py11
-rw-r--r--Lib/sha.py11
-rw-r--r--Lib/shlex.py4
-rw-r--r--Lib/subprocess.py16
-rw-r--r--Lib/tarfile.py244
-rw-r--r--Lib/test/dis_module.py5
-rw-r--r--Lib/test/infinite_reload.py7
-rw-r--r--Lib/test/output/test_pkg2
-rwxr-xr-xLib/test/regrtest.py6
-rw-r--r--Lib/test/test_MimeWriter.py291
-rw-r--r--Lib/test/test___all__.py3
-rw-r--r--Lib/test/test_builtin.py8
-rw-r--r--Lib/test/test_dis.py18
-rw-r--r--Lib/test/test_doctest.py2
-rw-r--r--Lib/test/test_hmac.py10
-rw-r--r--Lib/test/test_import.py76
-rw-r--r--Lib/test/test_importhooks.py4
-rw-r--r--Lib/test/test_inspect.py2
-rw-r--r--Lib/test/test_optparse.py6
-rw-r--r--Lib/test/test_os.py14
-rw-r--r--Lib/test/test_pkg.py3
-rw-r--r--Lib/test/test_subprocess.py8
-rw-r--r--Lib/test/test_sundry.py5
-rw-r--r--Lib/test/test_syntax.py18
-rw-r--r--Lib/test/test_sys.py41
-rw-r--r--Lib/test/test_tarfile.py245
-rw-r--r--Lib/test/test_tokenize.py4
-rw-r--r--Lib/test/test_traceback.py47
-rw-r--r--Lib/test/test_urllib.py77
-rw-r--r--Lib/test/test_xmlrpc.py7
-rw-r--r--Lib/test/testtar.tarbin256000 -> 264704 bytes
-rw-r--r--Lib/textwrap.py8
-rw-r--r--Lib/unittest.py16
-rw-r--r--Lib/urllib.py5
-rw-r--r--Lib/uuid.py8
-rw-r--r--Lib/wsgiref/handlers.py17
-rw-r--r--Lib/xmlrpclib.py2
53 files changed, 501 insertions, 1909 deletions
diff --git a/Lib/MimeWriter.py b/Lib/MimeWriter.py
deleted file mode 100644
index 58c0a0b..0000000
--- a/Lib/MimeWriter.py
+++ /dev/null
@@ -1,181 +0,0 @@
-"""Generic MIME writer.
-
-This module defines the class MimeWriter. The MimeWriter class implements
-a basic formatter for creating MIME multi-part files. It doesn't seek around
-the output file nor does it use large amounts of buffer space. You must write
-the parts out in the order that they should occur in the final file.
-MimeWriter does buffer the headers you add, allowing you to rearrange their
-order.
-
-"""
-
-
-import mimetools
-
-__all__ = ["MimeWriter"]
-
-class MimeWriter:
-
- """Generic MIME writer.
-
- Methods:
-
- __init__()
- addheader()
- flushheaders()
- startbody()
- startmultipartbody()
- nextpart()
- lastpart()
-
- A MIME writer is much more primitive than a MIME parser. It
- doesn't seek around on the output file, and it doesn't use large
- amounts of buffer space, so you have to write the parts in the
- order they should occur on the output file. It does buffer the
- headers you add, allowing you to rearrange their order.
-
- General usage is:
-
- f = <open the output file>
- w = MimeWriter(f)
- ...call w.addheader(key, value) 0 or more times...
-
- followed by either:
-
- f = w.startbody(content_type)
- ...call f.write(data) for body data...
-
- or:
-
- w.startmultipartbody(subtype)
- for each part:
- subwriter = w.nextpart()
- ...use the subwriter's methods to create the subpart...
- w.lastpart()
-
- The subwriter is another MimeWriter instance, and should be
- treated in the same way as the toplevel MimeWriter. This way,
- writing recursive body parts is easy.
-
- Warning: don't forget to call lastpart()!
-
- XXX There should be more state so calls made in the wrong order
- are detected.
-
- Some special cases:
-
- - startbody() just returns the file passed to the constructor;
- but don't use this knowledge, as it may be changed.
-
- - startmultipartbody() actually returns a file as well;
- this can be used to write the initial 'if you can read this your
- mailer is not MIME-aware' message.
-
- - If you call flushheaders(), the headers accumulated so far are
- written out (and forgotten); this is useful if you don't need a
- body part at all, e.g. for a subpart of type message/rfc822
- that's (mis)used to store some header-like information.
-
- - Passing a keyword argument 'prefix=<flag>' to addheader(),
- start*body() affects where the header is inserted; 0 means
- append at the end, 1 means insert at the start; default is
- append for addheader(), but insert for start*body(), which use
- it to determine where the Content-Type header goes.
-
- """
-
- def __init__(self, fp):
- self._fp = fp
- self._headers = []
-
- def addheader(self, key, value, prefix=0):
- """Add a header line to the MIME message.
-
- The key is the name of the header, where the value obviously provides
- the value of the header. The optional argument prefix determines
- where the header is inserted; 0 means append at the end, 1 means
- insert at the start. The default is to append.
-
- """
- lines = value.split("\n")
- while lines and not lines[-1]: del lines[-1]
- while lines and not lines[0]: del lines[0]
- for i in range(1, len(lines)):
- lines[i] = " " + lines[i].strip()
- value = "\n".join(lines) + "\n"
- line = key + ": " + value
- if prefix:
- self._headers.insert(0, line)
- else:
- self._headers.append(line)
-
- def flushheaders(self):
- """Writes out and forgets all headers accumulated so far.
-
- This is useful if you don't need a body part at all; for example,
- for a subpart of type message/rfc822 that's (mis)used to store some
- header-like information.
-
- """
- self._fp.writelines(self._headers)
- self._headers = []
-
- def startbody(self, ctype, plist=[], prefix=1):
- """Returns a file-like object for writing the body of the message.
-
- The content-type is set to the provided ctype, and the optional
- parameter, plist, provides additional parameters for the
- content-type declaration. The optional argument prefix determines
- where the header is inserted; 0 means append at the end, 1 means
- insert at the start. The default is to insert at the start.
-
- """
- for name, value in plist:
- ctype = ctype + ';\n %s=\"%s\"' % (name, value)
- self.addheader("Content-Type", ctype, prefix=prefix)
- self.flushheaders()
- self._fp.write("\n")
- return self._fp
-
- def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
- """Returns a file-like object for writing the body of the message.
-
- Additionally, this method initializes the multi-part code, where the
- subtype parameter provides the multipart subtype, the boundary
- parameter may provide a user-defined boundary specification, and the
- plist parameter provides optional parameters for the subtype. The
- optional argument, prefix, determines where the header is inserted;
- 0 means append at the end, 1 means insert at the start. The default
- is to insert at the start. Subparts should be created using the
- nextpart() method.
-
- """
- self._boundary = boundary or mimetools.choose_boundary()
- return self.startbody("multipart/" + subtype,
- [("boundary", self._boundary)] + plist,
- prefix=prefix)
-
- def nextpart(self):
- """Returns a new instance of MimeWriter which represents an
- individual part in a multipart message.
-
- This may be used to write the part as well as used for creating
- recursively complex multipart messages. The message must first be
- initialized with the startmultipartbody() method before using the
- nextpart() method.
-
- """
- self._fp.write("\n--" + self._boundary + "\n")
- return self.__class__(self._fp)
-
- def lastpart(self):
- """This is used to designate the last part of a multipart message.
-
- It should always be used when writing multipart messages.
-
- """
- self._fp.write("\n--" + self._boundary + "--\n")
-
-
-if __name__ == '__main__':
- import test.test_MimeWriter
diff --git a/Lib/SocketServer.py b/Lib/SocketServer.py
index 8e92b80..c6e71eb 100644
--- a/Lib/SocketServer.py
+++ b/Lib/SocketServer.py
@@ -518,12 +518,9 @@ class BaseRequestHandler:
self.request = request
self.client_address = client_address
self.server = server
- try:
- self.setup()
- self.handle()
- self.finish()
- finally:
- sys.exc_traceback = None # Help garbage collection
+ self.setup()
+ self.handle()
+ self.finish()
def setup(self):
pass
diff --git a/Lib/bsddb/test/test_thread.py b/Lib/bsddb/test/test_thread.py
index fca4466..df112b7 100644
--- a/Lib/bsddb/test/test_thread.py
+++ b/Lib/bsddb/test/test_thread.py
@@ -10,12 +10,6 @@ import tempfile
from pprint import pprint
from random import random
-try:
- True, False
-except NameError:
- True = 1
- False = 0
-
DASH = '-'
try:
diff --git a/Lib/ctypes/wintypes.py b/Lib/ctypes/wintypes.py
index a0fc0bb..e97b31d 100644
--- a/Lib/ctypes/wintypes.py
+++ b/Lib/ctypes/wintypes.py
@@ -147,7 +147,7 @@ class WIN32_FIND_DATAA(Structure):
("dwReserved0", DWORD),
("dwReserved1", DWORD),
("cFileName", c_char * MAX_PATH),
- ("cAlternameFileName", c_char * 14)]
+ ("cAlternateFileName", c_char * 14)]
class WIN32_FIND_DATAW(Structure):
_fields_ = [("dwFileAttributes", DWORD),
@@ -159,7 +159,7 @@ class WIN32_FIND_DATAW(Structure):
("dwReserved0", DWORD),
("dwReserved1", DWORD),
("cFileName", c_wchar * MAX_PATH),
- ("cAlternameFileName", c_wchar * 14)]
+ ("cAlternateFileName", c_wchar * 14)]
__all__ = ['ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE',
'DWORD', 'FILETIME', 'HACCEL', 'HANDLE', 'HBITMAP', 'HBRUSH',
diff --git a/Lib/dis.py b/Lib/dis.py
index f274606..dac7cae 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -23,13 +23,10 @@ def dis(x=None):
if hasattr(x, '__code__'):
x = x.__code__
if hasattr(x, '__dict__'):
- items = x.__dict__.items()
- items.sort()
+ items = sorted(x.__dict__.items())
for name, x1 in items:
- if type(x1) in (types.MethodType,
- types.FunctionType,
- types.CodeType,
- types.ClassType):
+ if isinstance(x1, (types.MethodType, types.FunctionType,
+ types.CodeType, types.ClassType, type)):
print("Disassembly of %s:" % name)
try:
dis(x1)
@@ -41,9 +38,8 @@ def dis(x=None):
elif isinstance(x, str):
disassemble_string(x)
else:
- raise TypeError, \
- "don't know how to disassemble %s objects" % \
- type(x).__name__
+ raise TypeError("don't know how to disassemble %s objects" %
+ type(x).__name__)
def distb(tb=None):
"""Disassemble a traceback (default: last traceback)."""
diff --git a/Lib/idlelib/StackViewer.py b/Lib/idlelib/StackViewer.py
index 6b7730b..79324ae 100644
--- a/Lib/idlelib/StackViewer.py
+++ b/Lib/idlelib/StackViewer.py
@@ -120,18 +120,3 @@ class VariablesTreeItem(ObjectTreeItem):
item = make_objecttreeitem(key + " =", value, setfunction)
sublist.append(item)
return sublist
-
-
-def _test():
- try:
- import testcode
- reload(testcode)
- except:
- sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
- from Tkinter import Tk
- root = Tk()
- StackBrowser(None, top=root)
- root.mainloop()
-
-if __name__ == "__main__":
- _test()
diff --git a/Lib/ihooks.py b/Lib/ihooks.py
index 733f2db..14a20a6 100644
--- a/Lib/ihooks.py
+++ b/Lib/ihooks.py
@@ -45,9 +45,7 @@ functionality along those lines.
If a module importer class supports dotted names, its import_module()
must return a different value depending on whether it is called on
behalf of a "from ... import ..." statement or not. (This is caused
-by the way the __import__ hook is used by the Python interpreter.) It
-would also do wise to install a different version of reload().
-
+by the way the __import__ hook is used by the Python interpreter.)
"""
@@ -379,17 +377,14 @@ class BasicModuleImporter(_Verbose):
def install(self):
self.save_import_module = __builtin__.__import__
- self.save_reload = __builtin__.reload
if not hasattr(__builtin__, 'unload'):
__builtin__.unload = None
self.save_unload = __builtin__.unload
__builtin__.__import__ = self.import_module
- __builtin__.reload = self.reload
__builtin__.unload = self.unload
def uninstall(self):
__builtin__.__import__ = self.save_import_module
- __builtin__.reload = self.save_reload
__builtin__.unload = self.save_unload
if not __builtin__.unload:
del __builtin__.unload
diff --git a/Lib/imputil.py b/Lib/imputil.py
index dbf0922..6d99ec1 100644
--- a/Lib/imputil.py
+++ b/Lib/imputil.py
@@ -40,9 +40,6 @@ class ImportManager:
self.namespace = namespace
namespace['__import__'] = self._import_hook
- ### fix this
- #namespace['reload'] = self._reload_hook
-
def uninstall(self):
"Restore the previous import mechanism."
self.namespace['__import__'] = self.previous_importer
@@ -194,22 +191,6 @@ class ImportManager:
return module
return None
- def _reload_hook(self, module):
- "Python calls this hook to reload a module."
-
- # reloading of a module may or may not be possible (depending on the
- # importer), but at least we can validate that it's ours to reload
- importer = module.__dict__.get('__importer__')
- if not importer:
- ### oops. now what...
- pass
-
- # okay. it is using the imputil system, and we must delegate it, but
- # we don't know what to do (yet)
- ### we should blast the module dict and do another get_code(). need to
- ### flesh this out and add proper docco...
- raise SystemError, "reload not yet implemented"
-
class Importer:
"Base class for replacing standard import functions."
@@ -682,7 +663,6 @@ def _test_revamp():
# flag to force absolute imports? (speeds _determine_import_context and
# checking for a relative module)
# insert names of archives into sys.path (see quote below)
-# note: reload does NOT blast module dict
# shift import mechanisms and policies around; provide for hooks, overrides
# (see quote below)
# add get_source stuff
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 4eb0392..0a62886 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -66,7 +66,7 @@ def currentframe():
try:
raise Exception
except:
- return sys.exc_traceback.tb_frame.f_back
+ return sys.exc_info()[2].tb_frame.f_back
if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
# done filching
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 00dd05b..084a932 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -629,7 +629,8 @@ class SysLogHandler(logging.Handler):
"""
Initialize a handler.
- If address is specified as a string, UNIX socket is used.
+ If address is specified as a string, a UNIX socket is used. To log to a
+ local syslogd, "SysLogHandler(address="/dev/log")" can be used.
If facility is not specified, LOG_USER is used.
"""
logging.Handler.__init__(self)
diff --git a/Lib/mimify.py b/Lib/mimify.py
deleted file mode 100755
index 6609e80..0000000
--- a/Lib/mimify.py
+++ /dev/null
@@ -1,464 +0,0 @@
-#! /usr/bin/env python
-
-"""Mimification and unmimification of mail messages.
-
-Decode quoted-printable parts of a mail message or encode using
-quoted-printable.
-
-Usage:
- mimify(input, output)
- unmimify(input, output, decode_base64 = 0)
-to encode and decode respectively. Input and output may be the name
-of a file or an open file object. Only a readline() method is used
-on the input file, only a write() method is used on the output file.
-When using file names, the input and output file names may be the
-same.
-
-Interactive usage:
- mimify.py -e [infile [outfile]]
- mimify.py -d [infile [outfile]]
-to encode and decode respectively. Infile defaults to standard
-input and outfile to standard output.
-"""
-
-# Configure
-MAXLEN = 200 # if lines longer than this, encode as quoted-printable
-CHARSET = 'ISO-8859-1' # default charset for non-US-ASCII mail
-QUOTE = '> ' # string replies are quoted with
-# End configure
-
-import re
-
-__all__ = ["mimify","unmimify","mime_encode_header","mime_decode_header"]
-
-qp = re.compile('^content-transfer-encoding:\\s*quoted-printable', re.I)
-base64_re = re.compile('^content-transfer-encoding:\\s*base64', re.I)
-mp = re.compile('^content-type:.*multipart/.*boundary="?([^;"\n]*)', re.I|re.S)
-chrset = re.compile('^(content-type:.*charset=")(us-ascii|iso-8859-[0-9]+)(".*)', re.I|re.S)
-he = re.compile('^-*\n')
-mime_code = re.compile('=([0-9a-f][0-9a-f])', re.I)
-mime_head = re.compile('=\\?iso-8859-1\\?q\\?([^? \t\n]+)\\?=', re.I)
-repl = re.compile('^subject:\\s+re: ', re.I)
-
-class File:
- """A simple fake file object that knows about limited read-ahead and
- boundaries. The only supported method is readline()."""
-
- def __init__(self, file, boundary):
- self.file = file
- self.boundary = boundary
- self.peek = None
-
- def readline(self):
- if self.peek is not None:
- return ''
- line = self.file.readline()
- if not line:
- return line
- if self.boundary:
- if line == self.boundary + '\n':
- self.peek = line
- return ''
- if line == self.boundary + '--\n':
- self.peek = line
- return ''
- return line
-
-class HeaderFile:
- def __init__(self, file):
- self.file = file
- self.peek = None
-
- def readline(self):
- if self.peek is not None:
- line = self.peek
- self.peek = None
- else:
- line = self.file.readline()
- if not line:
- return line
- if he.match(line):
- return line
- while 1:
- self.peek = self.file.readline()
- if len(self.peek) == 0 or \
- (self.peek[0] != ' ' and self.peek[0] != '\t'):
- return line
- line = line + self.peek
- self.peek = None
-
-def mime_decode(line):
- """Decode a single line of quoted-printable text to 8bit."""
- newline = ''
- pos = 0
- while 1:
- res = mime_code.search(line, pos)
- if res is None:
- break
- newline = newline + line[pos:res.start(0)] + \
- chr(int(res.group(1), 16))
- pos = res.end(0)
- return newline + line[pos:]
-
-def mime_decode_header(line):
- """Decode a header line to 8bit."""
- newline = ''
- pos = 0
- while 1:
- res = mime_head.search(line, pos)
- if res is None:
- break
- match = res.group(1)
- # convert underscores to spaces (before =XX conversion!)
- match = ' '.join(match.split('_'))
- newline = newline + line[pos:res.start(0)] + mime_decode(match)
- pos = res.end(0)
- return newline + line[pos:]
-
-def unmimify_part(ifile, ofile, decode_base64 = 0):
- """Convert a quoted-printable part of a MIME mail message to 8bit."""
- multipart = None
- quoted_printable = 0
- is_base64 = 0
- is_repl = 0
- if ifile.boundary and ifile.boundary[:2] == QUOTE:
- prefix = QUOTE
- else:
- prefix = ''
-
- # read header
- hfile = HeaderFile(ifile)
- while 1:
- line = hfile.readline()
- if not line:
- return
- if prefix and line[:len(prefix)] == prefix:
- line = line[len(prefix):]
- pref = prefix
- else:
- pref = ''
- line = mime_decode_header(line)
- if qp.match(line):
- quoted_printable = 1
- continue # skip this header
- if decode_base64 and base64_re.match(line):
- is_base64 = 1
- continue
- ofile.write(pref + line)
- if not prefix and repl.match(line):
- # we're dealing with a reply message
- is_repl = 1
- mp_res = mp.match(line)
- if mp_res:
- multipart = '--' + mp_res.group(1)
- if he.match(line):
- break
- if is_repl and (quoted_printable or multipart):
- is_repl = 0
-
- # read body
- while 1:
- line = ifile.readline()
- if not line:
- return
- line = re.sub(mime_head, '\\1', line)
- if prefix and line[:len(prefix)] == prefix:
- line = line[len(prefix):]
- pref = prefix
- else:
- pref = ''
-## if is_repl and len(line) >= 4 and line[:4] == QUOTE+'--' and line[-3:] != '--\n':
-## multipart = line[:-1]
- while multipart:
- if line == multipart + '--\n':
- ofile.write(pref + line)
- multipart = None
- line = None
- break
- if line == multipart + '\n':
- ofile.write(pref + line)
- nifile = File(ifile, multipart)
- unmimify_part(nifile, ofile, decode_base64)
- line = nifile.peek
- if not line:
- # premature end of file
- break
- continue
- # not a boundary between parts
- break
- if line and quoted_printable:
- while line[-2:] == '=\n':
- line = line[:-2]
- newline = ifile.readline()
- if newline[:len(QUOTE)] == QUOTE:
- newline = newline[len(QUOTE):]
- line = line + newline
- line = mime_decode(line)
- if line and is_base64 and not pref:
- import base64
- line = base64.decodestring(line)
- if line:
- ofile.write(pref + line)
-
-def unmimify(infile, outfile, decode_base64 = 0):
- """Convert quoted-printable parts of a MIME mail message to 8bit."""
- if type(infile) == type(''):
- ifile = open(infile)
- if type(outfile) == type('') and infile == outfile:
- import os
- d, f = os.path.split(infile)
- os.rename(infile, os.path.join(d, ',' + f))
- else:
- ifile = infile
- if type(outfile) == type(''):
- ofile = open(outfile, 'w')
- else:
- ofile = outfile
- nifile = File(ifile, None)
- unmimify_part(nifile, ofile, decode_base64)
- ofile.flush()
-
-mime_char = re.compile('[=\177-\377]') # quote these chars in body
-mime_header_char = re.compile('[=?\177-\377]') # quote these in header
-
-def mime_encode(line, header):
- """Code a single line as quoted-printable.
- If header is set, quote some extra characters."""
- if header:
- reg = mime_header_char
- else:
- reg = mime_char
- newline = ''
- pos = 0
- if len(line) >= 5 and line[:5] == 'From ':
- # quote 'From ' at the start of a line for stupid mailers
- newline = ('=%02x' % ord('F')).upper()
- pos = 1
- while 1:
- res = reg.search(line, pos)
- if res is None:
- break
- newline = newline + line[pos:res.start(0)] + \
- ('=%02x' % ord(res.group(0))).upper()
- pos = res.end(0)
- line = newline + line[pos:]
-
- newline = ''
- while len(line) >= 75:
- i = 73
- while line[i] == '=' or line[i-1] == '=':
- i = i - 1
- i = i + 1
- newline = newline + line[:i] + '=\n'
- line = line[i:]
- return newline + line
-
-mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)(?=[ \t)]|\n)')
-
-def mime_encode_header(line):
- """Code a single header line as quoted-printable."""
- newline = ''
- pos = 0
- while 1:
- res = mime_header.search(line, pos)
- if res is None:
- break
- newline = '%s%s%s=?%s?Q?%s?=' % \
- (newline, line[pos:res.start(0)], res.group(1),
- CHARSET, mime_encode(res.group(2), 1))
- pos = res.end(0)
- return newline + line[pos:]
-
-mv = re.compile('^mime-version:', re.I)
-cte = re.compile('^content-transfer-encoding:', re.I)
-iso_char = re.compile('[\177-\377]')
-
-def mimify_part(ifile, ofile, is_mime):
- """Convert an 8bit part of a MIME mail message to quoted-printable."""
- has_cte = is_qp = is_base64 = 0
- multipart = None
- must_quote_body = must_quote_header = has_iso_chars = 0
-
- header = []
- header_end = ''
- message = []
- message_end = ''
- # read header
- hfile = HeaderFile(ifile)
- while 1:
- line = hfile.readline()
- if not line:
- break
- if not must_quote_header and iso_char.search(line):
- must_quote_header = 1
- if mv.match(line):
- is_mime = 1
- if cte.match(line):
- has_cte = 1
- if qp.match(line):
- is_qp = 1
- elif base64_re.match(line):
- is_base64 = 1
- mp_res = mp.match(line)
- if mp_res:
- multipart = '--' + mp_res.group(1)
- if he.match(line):
- header_end = line
- break
- header.append(line)
-
- # read body
- while 1:
- line = ifile.readline()
- if not line:
- break
- if multipart:
- if line == multipart + '--\n':
- message_end = line
- break
- if line == multipart + '\n':
- message_end = line
- break
- if is_base64:
- message.append(line)
- continue
- if is_qp:
- while line[-2:] == '=\n':
- line = line[:-2]
- newline = ifile.readline()
- if newline[:len(QUOTE)] == QUOTE:
- newline = newline[len(QUOTE):]
- line = line + newline
- line = mime_decode(line)
- message.append(line)
- if not has_iso_chars:
- if iso_char.search(line):
- has_iso_chars = must_quote_body = 1
- if not must_quote_body:
- if len(line) > MAXLEN:
- must_quote_body = 1
-
- # convert and output header and body
- for line in header:
- if must_quote_header:
- line = mime_encode_header(line)
- chrset_res = chrset.match(line)
- if chrset_res:
- if has_iso_chars:
- # change us-ascii into iso-8859-1
- if chrset_res.group(2).lower() == 'us-ascii':
- line = '%s%s%s' % (chrset_res.group(1),
- CHARSET,
- chrset_res.group(3))
- else:
- # change iso-8859-* into us-ascii
- line = '%sus-ascii%s' % chrset_res.group(1, 3)
- if has_cte and cte.match(line):
- line = 'Content-Transfer-Encoding: '
- if is_base64:
- line = line + 'base64\n'
- elif must_quote_body:
- line = line + 'quoted-printable\n'
- else:
- line = line + '7bit\n'
- ofile.write(line)
- if (must_quote_header or must_quote_body) and not is_mime:
- ofile.write('Mime-Version: 1.0\n')
- ofile.write('Content-Type: text/plain; ')
- if has_iso_chars:
- ofile.write('charset="%s"\n' % CHARSET)
- else:
- ofile.write('charset="us-ascii"\n')
- if must_quote_body and not has_cte:
- ofile.write('Content-Transfer-Encoding: quoted-printable\n')
- ofile.write(header_end)
-
- for line in message:
- if must_quote_body:
- line = mime_encode(line, 0)
- ofile.write(line)
- ofile.write(message_end)
-
- line = message_end
- while multipart:
- if line == multipart + '--\n':
- # read bit after the end of the last part
- while 1:
- line = ifile.readline()
- if not line:
- return
- if must_quote_body:
- line = mime_encode(line, 0)
- ofile.write(line)
- if line == multipart + '\n':
- nifile = File(ifile, multipart)
- mimify_part(nifile, ofile, 1)
- line = nifile.peek
- if not line:
- # premature end of file
- break
- ofile.write(line)
- continue
- # unexpectedly no multipart separator--copy rest of file
- while 1:
- line = ifile.readline()
- if not line:
- return
- if must_quote_body:
- line = mime_encode(line, 0)
- ofile.write(line)
-
-def mimify(infile, outfile):
- """Convert 8bit parts of a MIME mail message to quoted-printable."""
- if type(infile) == type(''):
- ifile = open(infile)
- if type(outfile) == type('') and infile == outfile:
- import os
- d, f = os.path.split(infile)
- os.rename(infile, os.path.join(d, ',' + f))
- else:
- ifile = infile
- if type(outfile) == type(''):
- ofile = open(outfile, 'w')
- else:
- ofile = outfile
- nifile = File(ifile, None)
- mimify_part(nifile, ofile, 0)
- ofile.flush()
-
-import sys
-if __name__ == '__main__' or (len(sys.argv) > 0 and sys.argv[0] == 'mimify'):
- import getopt
- usage = 'Usage: mimify [-l len] -[ed] [infile [outfile]]'
-
- decode_base64 = 0
- opts, args = getopt.getopt(sys.argv[1:], 'l:edb')
- if len(args) not in (0, 1, 2):
- print(usage)
- sys.exit(1)
- if (('-e', '') in opts) == (('-d', '') in opts) or \
- ((('-b', '') in opts) and (('-d', '') not in opts)):
- print(usage)
- sys.exit(1)
- for o, a in opts:
- if o == '-e':
- encode = mimify
- elif o == '-d':
- encode = unmimify
- elif o == '-l':
- try:
- MAXLEN = int(a)
- except (ValueError, OverflowError):
- print(usage)
- sys.exit(1)
- elif o == '-b':
- decode_base64 = 1
- if len(args) == 0:
- encode_args = (sys.stdin, sys.stdout)
- elif len(args) == 1:
- encode_args = (args[0], sys.stdout)
- else:
- encode_args = (args[0], args[1])
- if decode_base64:
- encode_args = encode_args + (decode_base64,)
- encode(*encode_args)
diff --git a/Lib/optparse.py b/Lib/optparse.py
index 1fc07b5..516fd5d 100644
--- a/Lib/optparse.py
+++ b/Lib/optparse.py
@@ -816,12 +816,6 @@ class Option:
SUPPRESS_HELP = "SUPPRESS"+"HELP"
SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
-# For compatibility with Python 2.2
-try:
- True, False
-except NameError:
- (True, False) = (1, 0)
-
def isbasestring(x):
return isinstance(x, basestring)
diff --git a/Lib/os.py b/Lib/os.py
index 0ced882..d2a305e 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -388,13 +388,14 @@ def _execvpe(file, args, env=None):
else:
envpath = defpath
PATH = envpath.split(pathsep)
- saved_exc = None
+ last_exc = saved_exc = None
saved_tb = None
for dir in PATH:
fullname = path.join(dir, file)
try:
func(fullname, *argrest)
except error as e:
+ last_exc = e
tb = sys.exc_info()[2]
if (e.errno != ENOENT and e.errno != ENOTDIR
and saved_exc is None):
@@ -402,7 +403,7 @@ def _execvpe(file, args, env=None):
saved_tb = tb
if saved_exc:
raise error, saved_exc, saved_tb
- raise error, e, tb
+ raise error, last_exc, tb
# Change environ to automatically call putenv() if it exists
try:
diff --git a/Lib/plat-mac/buildtools.py b/Lib/plat-mac/buildtools.py
index 62c456c..5678a9f 100644
--- a/Lib/plat-mac/buildtools.py
+++ b/Lib/plat-mac/buildtools.py
@@ -13,6 +13,9 @@ import macresource
import EasyDialogs
import shutil
+import warnings
+warnings.warn("the buildtools module is deprecated", DeprecationWarning, 2)
+
BuildError = "BuildError"
diff --git a/Lib/plat-mac/cfmfile.py b/Lib/plat-mac/cfmfile.py
deleted file mode 100644
index df157fd..0000000
--- a/Lib/plat-mac/cfmfile.py
+++ /dev/null
@@ -1,183 +0,0 @@
-"""codefragments.py -- wrapper to modify code fragments."""
-
-# (c) 1998, Just van Rossum, Letterror
-
-__version__ = "0.8b3"
-__author__ = "jvr"
-
-import Carbon.File
-import struct
-from Carbon import Res
-import os
-import sys
-
-DEBUG = 0
-
-error = "cfm.error"
-
-BUFSIZE = 0x80000
-
-def mergecfmfiles(srclist, dst, architecture = 'fat'):
- """Merge all files in srclist into a new file dst.
-
- If architecture is given, only code fragments of that type will be used:
- "pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic"
- 68k code, since it does not use code fragments to begin with.
- If architecture is None, all fragments will be used, enabling FAT binaries.
- """
-
- srclist = list(srclist)
- for i in range(len(srclist)):
- srclist[i] = Carbon.File.pathname(srclist[i])
- dst = Carbon.File.pathname(dst)
-
- dstfile = open(dst, "wb")
- rf = Res.FSpOpenResFile(dst, 3)
- try:
- dstcfrg = CfrgResource()
- for src in srclist:
- srccfrg = CfrgResource(src)
- for frag in srccfrg.fragments:
- if frag.architecture == 'pwpc' and architecture == 'm68k':
- continue
- if frag.architecture == 'm68k' and architecture == 'pwpc':
- continue
- dstcfrg.append(frag)
-
- frag.copydata(dstfile)
-
- cfrgres = Res.Resource(dstcfrg.build())
- Res.UseResFile(rf)
- cfrgres.AddResource('cfrg', 0, "")
- finally:
- dstfile.close()
- rf = Res.CloseResFile(rf)
-
-
-class CfrgResource:
-
- def __init__(self, path = None):
- self.version = 1
- self.fragments = []
- self.path = path
- if path is not None and os.path.exists(path):
- currentresref = Res.CurResFile()
- resref = Res.FSpOpenResFile(path, 1)
- Res.UseResFile(resref)
- try:
- try:
- data = Res.Get1Resource('cfrg', 0).data
- except Res.Error:
- raise Res.Error, "no 'cfrg' resource found", sys.exc_traceback
- finally:
- Res.CloseResFile(resref)
- Res.UseResFile(currentresref)
- self.parse(data)
- if self.version != 1:
- raise error, "unknown 'cfrg' resource format"
-
- def parse(self, data):
- (res1, res2, self.version,
- res3, res4, res5, res6,
- self.memberCount) = struct.unpack("8l", data[:32])
- data = data[32:]
- while data:
- frag = FragmentDescriptor(self.path, data)
- data = data[frag.memberSize:]
- self.fragments.append(frag)
-
- def build(self):
- self.memberCount = len(self.fragments)
- data = struct.pack("8l", 0, 0, self.version, 0, 0, 0, 0, self.memberCount)
- for frag in self.fragments:
- data = data + frag.build()
- return data
-
- def append(self, frag):
- self.fragments.append(frag)
-
-
-class FragmentDescriptor:
-
- def __init__(self, path, data = None):
- self.path = path
- if data is not None:
- self.parse(data)
-
- def parse(self, data):
- self.architecture = data[:4]
- ( self.updatelevel,
- self.currentVersion,
- self.oldDefVersion,
- self.stacksize,
- self.applibdir,
- self.fragtype,
- self.where,
- self.offset,
- self.length,
- self.res1, self.res2,
- self.memberSize,) = struct.unpack("4lhBB4lh", data[4:42])
- pname = data[42:self.memberSize]
- self.name = pname[1:1+ord(pname[0])]
-
- def build(self):
- data = self.architecture
- data = data + struct.pack("4lhBB4l",
- self.updatelevel,
- self.currentVersion,
- self.oldDefVersion,
- self.stacksize,
- self.applibdir,
- self.fragtype,
- self.where,
- self.offset,
- self.length,
- self.res1, self.res2)
- self.memberSize = len(data) + 2 + 1 + len(self.name)
- # pad to 4 byte boundaries
- if self.memberSize % 4:
- self.memberSize = self.memberSize + 4 - (self.memberSize % 4)
- data = data + struct.pack("hb", self.memberSize, len(self.name))
- data = data + self.name
- data = data + '\000' * (self.memberSize - len(data))
- return data
-
- def getfragment(self):
- if self.where != 1:
- raise error, "can't read fragment, unsupported location"
- f = open(self.path, "rb")
- f.seek(self.offset)
- if self.length:
- frag = f.read(self.length)
- else:
- frag = f.read()
- f.close()
- return frag
-
- def copydata(self, outfile):
- if self.where != 1:
- raise error, "can't read fragment, unsupported location"
- infile = open(self.path, "rb")
- if self.length == 0:
- infile.seek(0, 2)
- self.length = infile.tell()
-
- # Position input file and record new offset from output file
- infile.seek(self.offset)
-
- # pad to 16 byte boundaries
- offset = outfile.tell()
- if offset % 16:
- offset = offset + 16 - (offset % 16)
- outfile.seek(offset)
- self.offset = offset
-
- l = self.length
- while l:
- if l > BUFSIZE:
- outfile.write(infile.read(BUFSIZE))
- l = l - BUFSIZE
- else:
- outfile.write(infile.read(l))
- l = 0
- infile.close()
diff --git a/Lib/posixfile.py b/Lib/posixfile.py
deleted file mode 100644
index 2fa600f..0000000
--- a/Lib/posixfile.py
+++ /dev/null
@@ -1,237 +0,0 @@
-"""Extended file operations available in POSIX.
-
-f = posixfile.open(filename, [mode, [bufsize]])
- will create a new posixfile object
-
-f = posixfile.fileopen(fileobject)
- will create a posixfile object from a builtin file object
-
-f.file()
- will return the original builtin file object
-
-f.dup()
- will return a new file object based on a new filedescriptor
-
-f.dup2(fd)
- will return a new file object based on the given filedescriptor
-
-f.flags(mode)
- will turn on the associated flag (merge)
- mode can contain the following characters:
-
- (character representing a flag)
- a append only flag
- c close on exec flag
- n no delay flag
- s synchronization flag
- (modifiers)
- ! turn flags 'off' instead of default 'on'
- = copy flags 'as is' instead of default 'merge'
- ? return a string in which the characters represent the flags
- that are set
-
- note: - the '!' and '=' modifiers are mutually exclusive.
- - the '?' modifier will return the status of the flags after they
- have been changed by other characters in the mode string
-
-f.lock(mode [, len [, start [, whence]]])
- will (un)lock a region
- mode can contain the following characters:
-
- (character representing type of lock)
- u unlock
- r read lock
- w write lock
- (modifiers)
- | wait until the lock can be granted
- ? return the first lock conflicting with the requested lock
- or 'None' if there is no conflict. The lock returned is in the
- format (mode, len, start, whence, pid) where mode is a
- character representing the type of lock ('r' or 'w')
-
- note: - the '?' modifier prevents a region from being locked; it is
- query only
-"""
-import warnings
-warnings.warn("The posixfile module is deprecated; "
- "fcntl.lockf() provides better locking", DeprecationWarning, 2)
-
-class _posixfile_:
- """File wrapper class that provides extra POSIX file routines."""
-
- states = ['open', 'closed']
-
- #
- # Internal routines
- #
- def __repr__(self):
- file = self._file_
- return "<%s posixfile '%s', mode '%s' at %s>" % \
- (self.states[file.closed], file.name, file.mode, \
- hex(id(self))[2:])
-
- #
- # Initialization routines
- #
- def open(self, name, mode='r', bufsize=-1):
- import __builtin__
- return self.fileopen(__builtin__.open(name, mode, bufsize))
-
- def fileopen(self, file):
- import types
- if repr(type(file)) != "<type 'file'>":
- raise TypeError, 'posixfile.fileopen() arg must be file object'
- self._file_ = file
- # Copy basic file methods
- for maybemethod in dir(file):
- if not maybemethod.startswith('_'):
- attr = getattr(file, maybemethod)
- if isinstance(attr, types.BuiltinMethodType):
- setattr(self, maybemethod, attr)
- return self
-
- #
- # New methods
- #
- def file(self):
- return self._file_
-
- def dup(self):
- import posix
-
- if not hasattr(posix, 'fdopen'):
- raise AttributeError, 'dup() method unavailable'
-
- return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
-
- def dup2(self, fd):
- import posix
-
- if not hasattr(posix, 'fdopen'):
- raise AttributeError, 'dup() method unavailable'
-
- posix.dup2(self._file_.fileno(), fd)
- return posix.fdopen(fd, self._file_.mode)
-
- def flags(self, *which):
- import fcntl, os
-
- if which:
- if len(which) > 1:
- raise TypeError, 'Too many arguments'
- which = which[0]
- else: which = '?'
-
- l_flags = 0
- if 'n' in which: l_flags = l_flags | os.O_NDELAY
- if 'a' in which: l_flags = l_flags | os.O_APPEND
- if 's' in which: l_flags = l_flags | os.O_SYNC
-
- file = self._file_
-
- if '=' not in which:
- cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
- if '!' in which: l_flags = cur_fl & ~ l_flags
- else: l_flags = cur_fl | l_flags
-
- l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
-
- if 'c' in which:
- arg = ('!' not in which) # 0 is don't, 1 is do close on exec
- l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
-
- if '?' in which:
- which = '' # Return current flags
- l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
- if os.O_APPEND & l_flags: which = which + 'a'
- if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
- which = which + 'c'
- if os.O_NDELAY & l_flags: which = which + 'n'
- if os.O_SYNC & l_flags: which = which + 's'
- return which
-
- def lock(self, how, *args):
- import struct, fcntl
-
- if 'w' in how: l_type = fcntl.F_WRLCK
- elif 'r' in how: l_type = fcntl.F_RDLCK
- elif 'u' in how: l_type = fcntl.F_UNLCK
- else: raise TypeError, 'no type of lock specified'
-
- if '|' in how: cmd = fcntl.F_SETLKW
- elif '?' in how: cmd = fcntl.F_GETLK
- else: cmd = fcntl.F_SETLK
-
- l_whence = 0
- l_start = 0
- l_len = 0
-
- if len(args) == 1:
- l_len = args[0]
- elif len(args) == 2:
- l_len, l_start = args
- elif len(args) == 3:
- l_len, l_start, l_whence = args
- elif len(args) > 3:
- raise TypeError, 'too many arguments'
-
- # Hack by davem@magnet.com to get locking to go on freebsd;
- # additions for AIX by Vladimir.Marangozov@imag.fr
- import sys, os
- if sys.platform in ('netbsd1',
- 'openbsd2',
- 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
- 'freebsd6', 'freebsd7',
- 'bsdos2', 'bsdos3', 'bsdos4'):
- flock = struct.pack('lxxxxlxxxxlhh', \
- l_start, l_len, os.getpid(), l_type, l_whence)
- elif sys.platform in ('aix3', 'aix4'):
- flock = struct.pack('hhlllii', \
- l_type, l_whence, l_start, l_len, 0, 0, 0)
- else:
- flock = struct.pack('hhllhh', \
- l_type, l_whence, l_start, l_len, 0, 0)
-
- flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
-
- if '?' in how:
- if sys.platform in ('netbsd1',
- 'openbsd2',
- 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
- 'bsdos2', 'bsdos3', 'bsdos4'):
- l_start, l_len, l_pid, l_type, l_whence = \
- struct.unpack('lxxxxlxxxxlhh', flock)
- elif sys.platform in ('aix3', 'aix4'):
- l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
- struct.unpack('hhlllii', flock)
- elif sys.platform == "linux2":
- l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
- struct.unpack('hhllhh', flock)
- else:
- l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
- struct.unpack('hhllhh', flock)
-
- if l_type != fcntl.F_UNLCK:
- if l_type == fcntl.F_RDLCK:
- return 'r', l_len, l_start, l_whence, l_pid
- else:
- return 'w', l_len, l_start, l_whence, l_pid
-
-def open(name, mode='r', bufsize=-1):
- """Public routine to open a file as a posixfile object."""
- return _posixfile_().open(name, mode, bufsize)
-
-def fileopen(file):
- """Public routine to get a posixfile object from a Python file object."""
- return _posixfile_().fileopen(file)
-
-#
-# Constants
-#
-SEEK_SET = 0
-SEEK_CUR = 1
-SEEK_END = 2
-
-#
-# End of posixfile.py
-#
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 9747456..e4074dc 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -271,12 +271,11 @@ def safeimport(path, forceload=0, cache={}):
# that inherits from another module that has changed).
if forceload and path in sys.modules:
if path not in sys.builtin_module_names:
- # Avoid simply calling reload() because it leaves names in
- # the currently loaded module lying around if they're not
- # defined in the new source file. Instead, remove the
- # module from sys.modules and re-import. Also remove any
- # submodules because they won't appear in the newly loaded
- # module's namespace if they're already in sys.modules.
+ # Remove the module from sys.modules and re-import to try
+ # and avoid problems with partially loaded modules.
+ # Also remove any submodules because they won't appear
+ # in the newly loaded module's namespace if they're already
+ # in sys.modules.
subs = [m for m in sys.modules if m.startswith(path + '.')]
for key in [path] + subs:
# Prevent garbage collection.
diff --git a/Lib/sha.py b/Lib/sha.py
deleted file mode 100644
index 9d914a9..0000000
--- a/Lib/sha.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Id$
-#
-# Copyright (C) 2005 Gregory P. Smith (greg@electricrain.com)
-# Licensed to PSF under a Contributor Agreement.
-
-from hashlib import sha1 as sha
-new = sha
-
-blocksize = 1 # legacy value (wrong in any useful sense)
-digest_size = 20
-digestsize = 20
diff --git a/Lib/shlex.py b/Lib/shlex.py
index 964046d..f034ab0 100644
--- a/Lib/shlex.py
+++ b/Lib/shlex.py
@@ -268,8 +268,8 @@ class shlex:
raise StopIteration
return token
-def split(s, comments=False):
- lex = shlex(s, posix=True)
+def split(s, comments=False, posix=True):
+ lex = shlex(s, posix=posix)
lex.whitespace_split = True
if not comments:
lex.commenters = ''
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index d46aa55..051f2d4 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -340,13 +340,6 @@ try:
except:
MAXFD = 256
-# True/False does not exist on 2.2.0
-try:
- False
-except NameError:
- False = 0
- True = 1
-
_active = []
def _cleanup():
@@ -479,9 +472,10 @@ class Popen(object):
if preexec_fn is not None:
raise ValueError("preexec_fn is not supported on Windows "
"platforms")
- if close_fds:
+ if close_fds and (stdin is not None or stdout is not None or
+ stderr is not None):
raise ValueError("close_fds is not supported on Windows "
- "platforms")
+ "platforms if you redirect stdin/stdout/stderr")
else:
# POSIX
if startupinfo is not None:
@@ -740,9 +734,7 @@ class Popen(object):
hp, ht, pid, tid = CreateProcess(executable, args,
# no special security
None, None,
- # must inherit handles to pass std
- # handles
- 1,
+ int(not close_fds),
creationflags,
env,
cwd,
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index ad1473f..ef6f1c7 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -127,6 +127,17 @@ GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
PAX_FIELDS = ("path", "linkpath", "size", "mtime",
"uid", "gid", "uname", "gname")
+# Fields in a pax header that are numbers, all other fields
+# are treated as strings.
+PAX_NUMBER_FIELDS = {
+ "atime": float,
+ "ctime": float,
+ "mtime": float,
+ "uid": int,
+ "gid": int,
+ "size": int
+}
+
#---------------------------------------------------------
# Bits used in the mode field, values in octal.
#---------------------------------------------------------
@@ -156,7 +167,7 @@ TOEXEC = 0001 # execute/search by other
#---------------------------------------------------------
ENCODING = sys.getfilesystemencoding()
if ENCODING is None:
- ENCODING = "ascii"
+ ENCODING = sys.getdefaultencoding()
#---------------------------------------------------------
# Some useful functions
@@ -220,6 +231,26 @@ def itn(n, digits=8, format=DEFAULT_FORMAT):
s = chr(0200) + s
return s
+def uts(s, encoding, errors):
+ """Convert a unicode object to a string.
+ """
+ if errors == "utf-8":
+ # An extra error handler similar to the -o invalid=UTF-8 option
+ # in POSIX.1-2001. Replace untranslatable characters with their
+ # UTF-8 representation.
+ try:
+ return s.encode(encoding, "strict")
+ except UnicodeEncodeError:
+ x = []
+ for c in s:
+ try:
+ x.append(c.encode(encoding, "strict"))
+ except UnicodeEncodeError:
+ x.append(c.encode("utf8"))
+ return "".join(x)
+ else:
+ return s.encode(encoding, errors)
+
def calc_chksums(buf):
"""Calculate the checksum for a member's header by summing up all
characters except for the chksum field which is treated as if
@@ -924,7 +955,7 @@ class TarInfo(object):
def __repr__(self):
return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
- def get_info(self):
+ def get_info(self, encoding, errors):
"""Return the TarInfo's attributes as a dictionary.
"""
info = {
@@ -946,24 +977,29 @@ class TarInfo(object):
if info["type"] == DIRTYPE and not info["name"].endswith("/"):
info["name"] += "/"
+ for key in ("name", "linkname", "uname", "gname"):
+ if type(info[key]) is unicode:
+ info[key] = info[key].encode(encoding, errors)
+
return info
- def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING):
+ def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="strict"):
"""Return a tar header as a string of 512 byte blocks.
"""
+ info = self.get_info(encoding, errors)
+
if format == USTAR_FORMAT:
- return self.create_ustar_header()
+ return self.create_ustar_header(info)
elif format == GNU_FORMAT:
- return self.create_gnu_header()
+ return self.create_gnu_header(info)
elif format == PAX_FORMAT:
- return self.create_pax_header(encoding)
+ return self.create_pax_header(info, encoding, errors)
else:
raise ValueError("invalid format")
- def create_ustar_header(self):
+ def create_ustar_header(self, info):
"""Return the object as a ustar header block.
"""
- info = self.get_info()
info["magic"] = POSIX_MAGIC
if len(info["linkname"]) > LENGTH_LINK:
@@ -974,10 +1010,9 @@ class TarInfo(object):
return self._create_header(info, USTAR_FORMAT)
- def create_gnu_header(self):
+ def create_gnu_header(self, info):
"""Return the object as a GNU header block sequence.
"""
- info = self.get_info()
info["magic"] = GNU_MAGIC
buf = ""
@@ -989,12 +1024,11 @@ class TarInfo(object):
return buf + self._create_header(info, GNU_FORMAT)
- def create_pax_header(self, encoding):
+ def create_pax_header(self, info, encoding, errors):
"""Return the object as a ustar header block. If it cannot be
represented this way, prepend a pax extended header sequence
with supplement information.
"""
- info = self.get_info()
info["magic"] = POSIX_MAGIC
pax_headers = self.pax_headers.copy()
@@ -1004,7 +1038,11 @@ class TarInfo(object):
("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK),
("uname", "uname", 32), ("gname", "gname", 32)):
- val = info[name].decode(encoding)
+ if hname in pax_headers:
+ # The pax header has priority.
+ continue
+
+ val = info[name].decode(encoding, errors)
# Try to encode the string as ASCII.
try:
@@ -1013,27 +1051,23 @@ class TarInfo(object):
pax_headers[hname] = val
continue
- if len(val) > length:
- if name == "name":
- # Try to squeeze a longname in the prefix and name fields as in
- # ustar format.
- try:
- info["prefix"], info["name"] = self._posix_split_name(info["name"])
- except ValueError:
- pax_headers[hname] = val
- else:
- continue
- else:
- pax_headers[hname] = val
+ if len(info[name]) > length:
+ pax_headers[hname] = val
# Test number fields for values that exceed the field limit or values
# that like to be stored as float.
for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)):
+ if name in pax_headers:
+ # The pax header has priority. Avoid overflow.
+ info[name] = 0
+ continue
+
val = info[name]
if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
pax_headers[name] = str(val)
info[name] = 0
+ # Create a pax extended header if necessary.
if pax_headers:
buf = self._create_pax_generic_header(pax_headers)
else:
@@ -1042,26 +1076,10 @@ class TarInfo(object):
return buf + self._create_header(info, USTAR_FORMAT)
@classmethod
- def create_pax_global_header(cls, pax_headers, encoding):
+ def create_pax_global_header(cls, pax_headers):
"""Return the object as a pax global header block sequence.
"""
- new_headers = {}
- for key, val in pax_headers.items():
- key = cls._to_unicode(key, encoding)
- val = cls._to_unicode(val, encoding)
- new_headers[key] = val
- return cls._create_pax_generic_header(new_headers, type=XGLTYPE)
-
- @staticmethod
- def _to_unicode(value, encoding):
- if isinstance(value, str):
- return value
- elif isinstance(value, (int, float)):
- return str(value)
- elif isinstance(value, str):
- return str(value, encoding)
- else:
- raise ValueError("unable to convert to unicode: %r" % value)
+ return cls._create_pax_generic_header(pax_headers, type=XGLTYPE)
def _posix_split_name(self, name):
"""Split a name longer than 100 chars into a prefix
@@ -1093,9 +1111,9 @@ class TarInfo(object):
" ", # checksum field
info.get("type", REGTYPE),
stn(info.get("linkname", ""), 100),
- stn(info.get("magic", ""), 8),
- stn(info.get("uname", ""), 32),
- stn(info.get("gname", ""), 32),
+ stn(info.get("magic", POSIX_MAGIC), 8),
+ stn(info.get("uname", "root"), 32),
+ stn(info.get("gname", "root"), 32),
itn(info.get("devmajor", 0), 8, format),
itn(info.get("devminor", 0), 8, format),
stn(info.get("prefix", ""), 155)
@@ -1256,12 +1274,9 @@ class TarInfo(object):
offset += self._block(self.size)
tarfile.offset = offset
- # Patch the TarInfo object with saved extended
+ # Patch the TarInfo object with saved global
# header information.
- for keyword, value in tarfile.pax_headers.items():
- if keyword in PAX_FIELDS:
- setattr(self, keyword, value)
- self.pax_headers[keyword] = value
+ self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
return self
@@ -1272,18 +1287,17 @@ class TarInfo(object):
buf = tarfile.fileobj.read(self._block(self.size))
# Fetch the next header and process it.
- b = tarfile.fileobj.read(BLOCKSIZE)
- t = self.frombuf(b)
- t.offset = self.offset
- next = t._proc_member(tarfile)
+ next = self.fromtarfile(tarfile)
+ if next is None:
+ raise HeaderError("missing subsequent header")
# Patch the TarInfo object from the next header with
# the longname information.
next.offset = self.offset
if self.type == GNUTYPE_LONGNAME:
- next.name = buf.rstrip(NUL)
+ next.name = nts(buf)
elif self.type == GNUTYPE_LONGLINK:
- next.linkname = buf.rstrip(NUL)
+ next.linkname = nts(buf)
return next
@@ -1358,21 +1372,10 @@ class TarInfo(object):
else:
pax_headers = tarfile.pax_headers.copy()
- # Fields in POSIX.1-2001 that are numbers, all other fields
- # are treated as UTF-8 strings.
- type_mapping = {
- "atime": float,
- "ctime": float,
- "mtime": float,
- "uid": int,
- "gid": int,
- "size": int
- }
-
# Parse pax header information. A record looks like that:
# "%d %s=%s\n" % (length, keyword, value). length is the size
# of the complete record including the length field itself and
- # the newline.
+ # the newline. keyword and value are both UTF-8 encoded strings.
regex = re.compile(r"(\d+) ([^=]+)=", re.U)
pos = 0
while True:
@@ -1385,35 +1388,55 @@ class TarInfo(object):
value = buf[match.end(2) + 1:match.start(1) + length - 1]
keyword = keyword.decode("utf8")
- keyword = keyword.encode(tarfile.encoding)
-
value = value.decode("utf8")
- if keyword in type_mapping:
- try:
- value = type_mapping[keyword](value)
- except ValueError:
- value = 0
- else:
- value = value.encode(tarfile.encoding)
pax_headers[keyword] = value
pos += length
- # Fetch the next header that will be patched with the
- # supplement information from the pax header (extended
- # only).
- t = self.fromtarfile(tarfile)
+ # Fetch the next header.
+ next = self.fromtarfile(tarfile)
- if self.type != XGLTYPE and t is not None:
- # Patch the TarInfo object from the next header with
- # the pax header's information.
- for keyword, value in pax_headers.items():
- if keyword in PAX_FIELDS:
- setattr(t, keyword, value)
- pax_headers[keyword] = value
- t.pax_headers = pax_headers.copy()
+ if self.type in (XHDTYPE, SOLARIS_XHDTYPE):
+ if next is None:
+ raise HeaderError("missing subsequent header")
- return t
+ # Patch the TarInfo object with the extended header info.
+ next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors)
+ next.offset = self.offset
+
+ if "size" in pax_headers:
+ # If the extended header replaces the size field,
+ # we need to recalculate the offset where the next
+ # header starts.
+ offset = next.offset_data
+ if next.isreg() or next.type not in SUPPORTED_TYPES:
+ offset += next._block(next.size)
+ tarfile.offset = offset
+
+ return next
+
+ def _apply_pax_info(self, pax_headers, encoding, errors):
+ """Replace fields with supplemental information from a previous
+ pax extended or global header.
+ """
+ for keyword, value in pax_headers.items():
+ if keyword not in PAX_FIELDS:
+ continue
+
+ if keyword == "path":
+ value = value.rstrip("/")
+
+ if keyword in PAX_NUMBER_FIELDS:
+ try:
+ value = PAX_NUMBER_FIELDS[keyword](value)
+ except ValueError:
+ value = 0
+ else:
+ value = uts(value, encoding, errors)
+
+ setattr(self, keyword, value)
+
+ self.pax_headers = pax_headers.copy()
def _block(self, count):
"""Round up a byte count by BLOCKSIZE and return it,
@@ -1464,8 +1487,9 @@ class TarFile(object):
format = DEFAULT_FORMAT # The format to use when creating an archive.
- encoding = ENCODING # Transfer UTF-8 strings from POSIX.1-2001
- # headers to this encoding.
+ encoding = ENCODING # Encoding for 8-bit character strings.
+
+ errors = None # Error handler for unicode conversion.
tarinfo = TarInfo # The default TarInfo class to use.
@@ -1473,7 +1497,7 @@ class TarFile(object):
def __init__(self, name=None, mode="r", fileobj=None, format=None,
tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
- pax_headers=None, debug=None, errorlevel=None):
+ errors=None, pax_headers=None, debug=None, errorlevel=None):
"""Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
read from an existing archive, 'a' to append data to an existing
file or 'w' to create a new file overwriting an existing one. `mode'
@@ -1492,7 +1516,7 @@ class TarFile(object):
# Create nonexistent files in append mode.
self.mode = "w"
self._mode = "wb"
- fileobj = _open(name, self._mode)
+ fileobj = bltn_open(name, self._mode)
self._extfileobj = False
else:
if name is None and hasattr(fileobj, "name"):
@@ -1514,6 +1538,19 @@ class TarFile(object):
self.ignore_zeros = ignore_zeros
if encoding is not None:
self.encoding = encoding
+
+ if errors is not None:
+ self.errors = errors
+ elif mode == "r":
+ self.errors = "utf-8"
+ else:
+ self.errors = "strict"
+
+ if pax_headers is not None and self.format == PAX_FORMAT:
+ self.pax_headers = pax_headers
+ else:
+ self.pax_headers = {}
+
if debug is not None:
self.debug = debug
if errorlevel is not None:
@@ -1526,7 +1563,6 @@ class TarFile(object):
self.offset = 0 # current position in the archive file
self.inodes = {} # dictionary caching the inodes of
# archive members already added
- self.pax_headers = {} # save contents of global pax headers
if self.mode == "r":
self.firstmember = None
@@ -1545,9 +1581,8 @@ class TarFile(object):
if self.mode in "aw":
self._loaded = True
- if pax_headers:
- buf = self.tarinfo.create_pax_global_header(
- pax_headers.copy(), self.encoding)
+ if self.pax_headers:
+ buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy())
self.fileobj.write(buf)
self.offset += len(buf)
@@ -1669,7 +1704,7 @@ class TarFile(object):
raise CompressionError("gzip module is not available")
if fileobj is None:
- fileobj = _open(name, mode + "b")
+ fileobj = bltn_open(name, mode + "b")
try:
t = cls.taropen(name, mode,
@@ -1819,8 +1854,6 @@ class TarFile(object):
self.inodes[inode] = arcname
elif stat.S_ISDIR(stmd):
type = DIRTYPE
- if arcname[-1:] != "/":
- arcname += "/"
elif stat.S_ISFIFO(stmd):
type = FIFOTYPE
elif stat.S_ISLNK(stmd):
@@ -1930,7 +1963,7 @@ class TarFile(object):
# Append the tar header and data to the archive.
if tarinfo.isreg():
- f = _open(name, "rb")
+ f = bltn_open(name, "rb")
self.addfile(tarinfo, f)
f.close()
@@ -1954,7 +1987,7 @@ class TarFile(object):
tarinfo = copy.copy(tarinfo)
- buf = tarinfo.tobuf(self.format, self.encoding)
+ buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
self.fileobj.write(buf)
self.offset += len(buf)
@@ -2141,7 +2174,7 @@ class TarFile(object):
"""Make a file called targetpath.
"""
source = self.extractfile(tarinfo)
- target = _open(targetpath, "wb")
+ target = bltn_open(targetpath, "wb")
copyfileobj(source, target)
source.close()
target.close()
@@ -2483,4 +2516,5 @@ def is_tarfile(name):
except TarError:
return False
+bltn_open = open
open = TarFile.open
diff --git a/Lib/test/dis_module.py b/Lib/test/dis_module.py
new file mode 100644
index 0000000..afbf600
--- /dev/null
+++ b/Lib/test/dis_module.py
@@ -0,0 +1,5 @@
+
+# A simple module for testing the dis module.
+
+def f(): pass
+def g(): pass
diff --git a/Lib/test/infinite_reload.py b/Lib/test/infinite_reload.py
deleted file mode 100644
index bfbec91..0000000
--- a/Lib/test/infinite_reload.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# For testing http://python.org/sf/742342, which reports that Python
-# segfaults (infinite recursion in C) in the presence of infinite
-# reload()ing. This module is imported by test_import.py:test_infinite_reload
-# to make sure this doesn't happen any more.
-
-import infinite_reload
-reload(infinite_reload)
diff --git a/Lib/test/output/test_pkg b/Lib/test/output/test_pkg
index 8a5ab8d..d1a891b 100644
--- a/Lib/test/output/test_pkg
+++ b/Lib/test/output/test_pkg
@@ -15,8 +15,6 @@ running test t3
t3 loading
t3.sub.subsub loading
t3 t3.sub t3.sub.subsub
-t3 loading
-t3.sub.subsub loading
running test t4
t4 loading
t4.sub.subsub loading
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 90a030d..de0b9f0 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -669,7 +669,8 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
indirect_test()
else:
def run_the_test():
- reload(the_module)
+ del sys.modules[the_module.__name__]
+ exec('import ' + the_module.__name__)
deltas = []
nwarmup, ntracked, fname = huntrleaks
@@ -841,7 +842,6 @@ _expectations = {
test_signal
test_sunaudiodev
test_threadsignals
- test_timing
test_wait3
test_wait4
""",
@@ -894,7 +894,6 @@ _expectations = {
test_sunaudiodev
test_sundry
test_tarfile
- test_timing
""",
'unixware7':
"""
@@ -992,7 +991,6 @@ _expectations = {
test_threaded_import
test_threadedtempfile
test_threading
- test_timing
""",
'darwin':
"""
diff --git a/Lib/test/test_MimeWriter.py b/Lib/test/test_MimeWriter.py
deleted file mode 100644
index feca163..0000000
--- a/Lib/test/test_MimeWriter.py
+++ /dev/null
@@ -1,291 +0,0 @@
-"""Test program for MimeWriter module.
-
-The test program was too big to comfortably fit in the MimeWriter
-class, so it's here in its own file.
-
-This should generate Barry's example, modulo some quotes and newlines.
-
-"""
-
-import unittest, sys, StringIO
-from test.test_support import run_unittest
-
-from MimeWriter import MimeWriter
-
-SELLER = '''\
-INTERFACE Seller-1;
-
-TYPE Seller = OBJECT
- DOCUMENTATION "A simple Seller interface to test ILU"
- METHODS
- price():INTEGER,
- END;
-'''
-
-BUYER = '''\
-class Buyer:
- def __setup__(self, maxprice):
- self._maxprice = maxprice
-
- def __main__(self, kos):
- """Entry point upon arrival at a new KOS."""
- broker = kos.broker()
- # B4 == Barry's Big Bass Business :-)
- seller = broker.lookup('Seller_1.Seller', 'B4')
- if seller:
- price = seller.price()
- print 'Seller wants $', price, '... '
- if price > self._maxprice:
- print 'too much!'
- else:
- print "I'll take it!"
- else:
- print 'no seller found here'
-''' # Don't ask why this comment is here
-
-STATE = '''\
-# instantiate a buyer instance and put it in a magic place for the KOS
-# to find.
-__kp__ = Buyer()
-__kp__.__setup__(500)
-'''
-
-SIMPLE_METADATA = [
- ("Interpreter", "python"),
- ("Interpreter-Version", "1.3"),
- ("Owner-Name", "Barry Warsaw"),
- ("Owner-Rendezvous", "bwarsaw@cnri.reston.va.us"),
- ("Home-KSS", "kss.cnri.reston.va.us"),
- ("Identifier", "hdl://cnri.kss/my_first_knowbot"),
- ("Launch-Date", "Mon Feb 12 16:39:03 EST 1996"),
- ]
-
-COMPLEX_METADATA = [
- ("Metadata-Type", "complex"),
- ("Metadata-Key", "connection"),
- ("Access", "read-only"),
- ("Connection-Description", "Barry's Big Bass Business"),
- ("Connection-Id", "B4"),
- ("Connection-Direction", "client"),
- ]
-
-EXTERNAL_METADATA = [
- ("Metadata-Type", "complex"),
- ("Metadata-Key", "generic-interface"),
- ("Access", "read-only"),
- ("Connection-Description", "Generic Interface for All Knowbots"),
- ("Connection-Id", "generic-kp"),
- ("Connection-Direction", "client"),
- ]
-
-
-OUTPUT = '''\
-From: bwarsaw@cnri.reston.va.us
-Date: Mon Feb 12 17:21:48 EST 1996
-To: kss-submit@cnri.reston.va.us
-MIME-Version: 1.0
-Content-Type: multipart/knowbot;
- boundary="801spam999";
- version="0.1"
-
-This is a multi-part message in MIME format.
-
---801spam999
-Content-Type: multipart/knowbot-metadata;
- boundary="802spam999"
-
-
---802spam999
-Content-Type: message/rfc822
-KP-Metadata-Type: simple
-KP-Access: read-only
-
-KPMD-Interpreter: python
-KPMD-Interpreter-Version: 1.3
-KPMD-Owner-Name: Barry Warsaw
-KPMD-Owner-Rendezvous: bwarsaw@cnri.reston.va.us
-KPMD-Home-KSS: kss.cnri.reston.va.us
-KPMD-Identifier: hdl://cnri.kss/my_first_knowbot
-KPMD-Launch-Date: Mon Feb 12 16:39:03 EST 1996
-
---802spam999
-Content-Type: text/isl
-KP-Metadata-Type: complex
-KP-Metadata-Key: connection
-KP-Access: read-only
-KP-Connection-Description: Barry's Big Bass Business
-KP-Connection-Id: B4
-KP-Connection-Direction: client
-
-INTERFACE Seller-1;
-
-TYPE Seller = OBJECT
- DOCUMENTATION "A simple Seller interface to test ILU"
- METHODS
- price():INTEGER,
- END;
-
---802spam999
-Content-Type: message/external-body;
- access-type="URL";
- URL="hdl://cnri.kss/generic-knowbot"
-
-Content-Type: text/isl
-KP-Metadata-Type: complex
-KP-Metadata-Key: generic-interface
-KP-Access: read-only
-KP-Connection-Description: Generic Interface for All Knowbots
-KP-Connection-Id: generic-kp
-KP-Connection-Direction: client
-
-
---802spam999--
-
---801spam999
-Content-Type: multipart/knowbot-code;
- boundary="803spam999"
-
-
---803spam999
-Content-Type: text/plain
-KP-Module-Name: BuyerKP
-
-class Buyer:
- def __setup__(self, maxprice):
- self._maxprice = maxprice
-
- def __main__(self, kos):
- """Entry point upon arrival at a new KOS."""
- broker = kos.broker()
- # B4 == Barry's Big Bass Business :-)
- seller = broker.lookup('Seller_1.Seller', 'B4')
- if seller:
- price = seller.price()
- print 'Seller wants $', price, '... '
- if price > self._maxprice:
- print 'too much!'
- else:
- print "I'll take it!"
- else:
- print 'no seller found here'
-
---803spam999--
-
---801spam999
-Content-Type: multipart/knowbot-state;
- boundary="804spam999"
-KP-Main-Module: main
-
-
---804spam999
-Content-Type: text/plain
-KP-Module-Name: main
-
-# instantiate a buyer instance and put it in a magic place for the KOS
-# to find.
-__kp__ = Buyer()
-__kp__.__setup__(500)
-
---804spam999--
-
---801spam999--
-'''
-
-class MimewriterTest(unittest.TestCase):
-
- def test(self):
- buf = StringIO.StringIO()
-
- # Toplevel headers
-
- toplevel = MimeWriter(buf)
- toplevel.addheader("From", "bwarsaw@cnri.reston.va.us")
- toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996")
- toplevel.addheader("To", "kss-submit@cnri.reston.va.us")
- toplevel.addheader("MIME-Version", "1.0")
-
- # Toplevel body parts
-
- f = toplevel.startmultipartbody("knowbot", "801spam999",
- [("version", "0.1")], prefix=0)
- f.write("This is a multi-part message in MIME format.\n")
-
- # First toplevel body part: metadata
-
- md = toplevel.nextpart()
- md.startmultipartbody("knowbot-metadata", "802spam999")
-
- # Metadata part 1
-
- md1 = md.nextpart()
- md1.addheader("KP-Metadata-Type", "simple")
- md1.addheader("KP-Access", "read-only")
- m = MimeWriter(md1.startbody("message/rfc822"))
- for key, value in SIMPLE_METADATA:
- m.addheader("KPMD-" + key, value)
- m.flushheaders()
- del md1
-
- # Metadata part 2
-
- md2 = md.nextpart()
- for key, value in COMPLEX_METADATA:
- md2.addheader("KP-" + key, value)
- f = md2.startbody("text/isl")
- f.write(SELLER)
- del md2
-
- # Metadata part 3
-
- md3 = md.nextpart()
- f = md3.startbody("message/external-body",
- [("access-type", "URL"),
- ("URL", "hdl://cnri.kss/generic-knowbot")])
- m = MimeWriter(f)
- for key, value in EXTERNAL_METADATA:
- md3.addheader("KP-" + key, value)
- md3.startbody("text/isl")
- # Phantom body doesn't need to be written
-
- md.lastpart()
-
- # Second toplevel body part: code
-
- code = toplevel.nextpart()
- code.startmultipartbody("knowbot-code", "803spam999")
-
- # Code: buyer program source
-
- buyer = code.nextpart()
- buyer.addheader("KP-Module-Name", "BuyerKP")
- f = buyer.startbody("text/plain")
- f.write(BUYER)
-
- code.lastpart()
-
- # Third toplevel body part: state
-
- state = toplevel.nextpart()
- state.addheader("KP-Main-Module", "main")
- state.startmultipartbody("knowbot-state", "804spam999")
-
- # State: a bunch of assignments
-
- st = state.nextpart()
- st.addheader("KP-Module-Name", "main")
- f = st.startbody("text/plain")
- f.write(STATE)
-
- state.lastpart()
-
- # End toplevel body parts
-
- toplevel.lastpart()
-
- self.assertEqual(buf.getvalue(), OUTPUT)
-
-def test_main():
- run_unittest(MimewriterTest)
-
-if __name__ == '__main__':
- test_main()
diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py
index cc3780d..f5dd431 100644
--- a/Lib/test/test___all__.py
+++ b/Lib/test/test___all__.py
@@ -1,7 +1,6 @@
import unittest
from test.test_support import verbose, run_unittest
import sys
-import warnings
class AllTest(unittest.TestCase):
@@ -34,7 +33,6 @@ class AllTest(unittest.TestCase):
self.check_all("CGIHTTPServer")
self.check_all("ConfigParser")
self.check_all("Cookie")
- self.check_all("MimeWriter")
self.check_all("Queue")
self.check_all("SimpleHTTPServer")
self.check_all("SocketServer")
@@ -92,7 +90,6 @@ class AllTest(unittest.TestCase):
self.check_all("mhlib")
self.check_all("mimetools")
self.check_all("mimetypes")
- self.check_all("mimify")
self.check_all("multifile")
self.check_all("netrc")
self.check_all("nntplib")
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 4e1375a..1c1998d 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1485,14 +1485,6 @@ class BuiltinTest(unittest.TestCase):
fp.close()
unlink(TESTFN)
- def test_reload(self):
- import marshal
- reload(marshal)
- import string
- reload(string)
- ## import sys
- ## self.assertRaises(ImportError, reload, sys)
-
def test_repr(self):
self.assertEqual(repr(''), '\'\'')
self.assertEqual(repr(0), '0')
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index dfb307d..f1bd3e7 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -89,6 +89,18 @@ _BIG_LINENO_FORMAT = """\
7 RETURN_VALUE
"""
+dis_module_expected_results = """\
+Disassembly of f:
+ 4 0 LOAD_CONST 0 (None)
+ 3 RETURN_VALUE
+
+Disassembly of g:
+ 5 0 LOAD_CONST 0 (None)
+ 3 RETURN_VALUE
+
+"""
+
+
class DisTests(unittest.TestCase):
def do_disassembly_test(self, func, expected):
s = StringIO.StringIO()
@@ -127,6 +139,7 @@ class DisTests(unittest.TestCase):
self.do_disassembly_test(bug708901, dis_bug708901)
def test_bug_1333982(self):
+ # XXX: re-enable this test!
# This one is checking bytecodes generated for an `assert` statement,
# so fails if the tests are run with -O. Skip this test then.
pass # Test has been disabled due to change in the way
@@ -153,9 +166,12 @@ class DisTests(unittest.TestCase):
expected = _BIG_LINENO_FORMAT % (i + 2)
self.do_disassembly_test(func(i), expected)
+ def test_big_linenos(self):
+ from test import dis_module
+ self.do_disassembly_test(dis_module, dis_module_expected_results)
+
def test_main():
run_unittest(DisTests)
-
if __name__ == "__main__":
test_main()
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 3adb98c..5730a59 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -2409,7 +2409,7 @@ import trace, sys, re, StringIO
def test_coverage(coverdir):
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,],
trace=0, count=1)
- tracer.run('reload(doctest); test_main()')
+ tracer.run('test_main()')
r = tracer.results()
print('Writing coverage results...')
r.write_results(show_missing=True, summary=True,
diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py
index 9d094d2..d28490d 100644
--- a/Lib/test/test_hmac.py
+++ b/Lib/test/test_hmac.py
@@ -1,5 +1,5 @@
import hmac
-import sha
+from hashlib import sha1
import unittest
from test import test_support
@@ -43,7 +43,7 @@ class TestVectorsTestCase(unittest.TestCase):
def test_sha_vectors(self):
def shatest(key, data, digest):
- h = hmac.HMAC(key, data, digestmod=sha)
+ h = hmac.HMAC(key, data, digestmod=sha1)
self.assertEqual(h.hexdigest().upper(), digest.upper())
shatest(chr(0x0b) * 20,
@@ -95,11 +95,11 @@ class ConstructorTestCase(unittest.TestCase):
def test_withmodule(self):
# Constructor call with text and digest module.
- import sha
+ from hashlib import sha1
try:
- h = hmac.HMAC("key", "", sha)
+ h = hmac.HMAC("key", "", sha1)
except:
- self.fail("Constructor call with sha module raised exception.")
+ self.fail("Constructor call with hashlib.sha1 raised exception.")
class SanityTestCase(unittest.TestCase):
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index 87907c8..193de40 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -6,6 +6,7 @@ import random
import sys
import py_compile
import warnings
+from test.test_support import unlink
def remove_files(name):
@@ -63,22 +64,9 @@ class ImportTest(unittest.TestCase):
self.assertEquals(mod.b, b,
"module loaded (%s) but contents invalid" % mod)
finally:
- os.unlink(source)
-
- try:
- try:
- reload(mod)
- except ImportError as err:
- self.fail("import from .pyc/.pyo failed: %s" % err)
- finally:
- try:
- os.unlink(pyc)
- except OSError:
- pass
- try:
- os.unlink(pyo)
- except OSError:
- pass
+ unlink(source)
+ unlink(pyc)
+ unlink(pyo)
del sys.modules[TESTFN]
sys.path.insert(0, os.curdir)
@@ -136,6 +124,8 @@ class ImportTest(unittest.TestCase):
# New in 2.4, we shouldn't be able to import that no matter how often
# we try.
sys.path.insert(0, os.curdir)
+ if TESTFN in sys.modules:
+ del sys.modules[TESTFN]
try:
for i in 1, 2, 3:
try:
@@ -149,60 +139,6 @@ class ImportTest(unittest.TestCase):
sys.path.pop(0)
remove_files(TESTFN)
- def test_failing_reload(self):
- # A failing reload should leave the module object in sys.modules.
- source = TESTFN + os.extsep + "py"
- f = open(source, "w")
- print("a = 1", file=f)
- print("b = 2", file=f)
- f.close()
-
- sys.path.insert(0, os.curdir)
- try:
- mod = __import__(TESTFN)
- self.assert_(TESTFN in sys.modules, "expected module in sys.modules")
- self.assertEquals(mod.a, 1, "module has wrong attribute values")
- self.assertEquals(mod.b, 2, "module has wrong attribute values")
-
- # On WinXP, just replacing the .py file wasn't enough to
- # convince reload() to reparse it. Maybe the timestamp didn't
- # move enough. We force it to get reparsed by removing the
- # compiled file too.
- remove_files(TESTFN)
-
- # Now damage the module.
- f = open(source, "w")
- print("a = 10", file=f)
- print("b = 20//0", file=f)
- f.close()
-
- self.assertRaises(ZeroDivisionError, reload, mod)
-
- # But we still expect the module to be in sys.modules.
- mod = sys.modules.get(TESTFN)
- self.failIf(mod is None, "expected module to still be in sys.modules")
-
- # We should have replaced a w/ 10, but the old b value should
- # stick.
- self.assertEquals(mod.a, 10, "module has wrong attribute values")
- self.assertEquals(mod.b, 2, "module has wrong attribute values")
-
- finally:
- sys.path.pop(0)
- remove_files(TESTFN)
- if TESTFN in sys.modules:
- del sys.modules[TESTFN]
-
- def test_infinite_reload(self):
- # Bug #742342 reports that Python segfaults (infinite recursion in C)
- # when faced with self-recursive reload()ing.
-
- sys.path.insert(0, os.path.dirname(__file__))
- try:
- import infinite_reload
- finally:
- sys.path.pop(0)
-
def test_import_name_binding(self):
# import x.y.z binds x in the current namespace
import test as x
diff --git a/Lib/test/test_importhooks.py b/Lib/test/test_importhooks.py
index 02268ab..18f3fc4 100644
--- a/Lib/test/test_importhooks.py
+++ b/Lib/test/test_importhooks.py
@@ -190,10 +190,6 @@ class ImportHooksTestCase(ImportHooksBaseTestCase):
import reloadmodule
self.failIf(hasattr(reloadmodule,'reloaded'))
- TestImporter.modules['reloadmodule'] = (False, reload_co)
- reload(reloadmodule)
- self.failUnless(hasattr(reloadmodule,'reloaded'))
-
import hooktestpackage.newrel
self.assertEqual(hooktestpackage.newrel.get_name(),
"hooktestpackage.newrel")
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 6fe1437..bdd7c34 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -26,7 +26,7 @@ import __builtin__
try:
1/0
except:
- tb = sys.exc_traceback
+ tb = sys.exc_info()[2]
git = mod.StupidGit()
diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py
index 811ec34..751f7a2 100644
--- a/Lib/test/test_optparse.py
+++ b/Lib/test/test_optparse.py
@@ -27,12 +27,6 @@ from optparse import make_option, Option, IndentedHelpFormatter, \
from optparse import _match_abbrev
from optparse import _parse_num
-# Do the right thing with boolean values for all known Python versions.
-try:
- True, False
-except NameError:
- (True, False) = (1, 0)
-
retype = type(re.compile(''))
class InterceptedError(Exception):
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index ed044f6..9673172 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -381,7 +381,7 @@ class WalkTests(unittest.TestCase):
os.remove(dirname)
os.rmdir(test_support.TESTFN)
-class MakedirTests (unittest.TestCase):
+class MakedirTests(unittest.TestCase):
def setUp(self):
os.mkdir(test_support.TESTFN)
@@ -400,9 +400,6 @@ class MakedirTests (unittest.TestCase):
'dir5', 'dir6')
os.makedirs(path)
-
-
-
def tearDown(self):
path = os.path.join(test_support.TESTFN, 'dir1', 'dir2', 'dir3',
'dir4', 'dir5', 'dir6')
@@ -414,7 +411,7 @@ class MakedirTests (unittest.TestCase):
os.removedirs(path)
-class DevNullTests (unittest.TestCase):
+class DevNullTests(unittest.TestCase):
def test_devnull(self):
f = open(os.devnull, 'w')
f.write('hello')
@@ -423,7 +420,7 @@ class DevNullTests (unittest.TestCase):
self.assertEqual(f.read(), '')
f.close()
-class URandomTests (unittest.TestCase):
+class URandomTests(unittest.TestCase):
def test_urandom(self):
try:
self.assertEqual(len(os.urandom(1)), 1)
@@ -433,6 +430,10 @@ class URandomTests (unittest.TestCase):
except NotImplementedError:
pass
+class ExecTests(unittest.TestCase):
+ def test_execvpe_with_bad_program(self):
+ self.assertRaises(OSError, os.execvpe, 'no such app-', [], None)
+
class Win32ErrorTests(unittest.TestCase):
def test_rename(self):
self.assertRaises(WindowsError, os.rename, test_support.TESTFN, test_support.TESTFN+".bak")
@@ -469,6 +470,7 @@ def test_main():
MakedirTests,
DevNullTests,
URandomTests,
+ ExecTests,
Win32ErrorTests
)
diff --git a/Lib/test/test_pkg.py b/Lib/test/test_pkg.py
index ad9cc1a..1a3f2a9 100644
--- a/Lib/test/test_pkg.py
+++ b/Lib/test/test_pkg.py
@@ -120,9 +120,6 @@ print(dir())
"""
import t3.sub.subsub
print(t3.__name__, t3.sub.__name__, t3.sub.subsub.__name__)
-reload(t3)
-reload(t3.sub)
-reload(t3.sub.subsub)
"""),
("t4", [
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 0592787..ec004bf 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -604,8 +604,16 @@ class ProcessTestCase(unittest.TestCase):
self.assertRaises(ValueError, subprocess.call,
[sys.executable,
"-c", "import sys; sys.exit(47)"],
+ stdout=subprocess.PIPE,
close_fds=True)
+ def test_close_fds(self):
+ # close file descriptors
+ rc = subprocess.call([sys.executable, "-c",
+ "import sys; sys.exit(47)"],
+ close_fds=True)
+ self.assertEqual(rc, 47)
+
def test_shell_sequence(self):
# Run command through the shell (sequence)
newenv = os.environ.copy()
diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py
index eb4149f..3c0346d 100644
--- a/Lib/test/test_sundry.py
+++ b/Lib/test/test_sundry.py
@@ -4,9 +4,6 @@ from test.test_support import guard_warnings_filter
import warnings
with guard_warnings_filter():
- warnings.filterwarnings('ignore', r".*posixfile",
- DeprecationWarning)
-
from test.test_support import verbose
import BaseHTTPServer
@@ -33,7 +30,6 @@ with guard_warnings_filter():
import linecache
import macurl2path
import mailcap
- import mimify
import mutex
import nntplib
import nturl2path
@@ -42,7 +38,6 @@ with guard_warnings_filter():
import pdb
import pipes
#import poplib
- import posixfile
import pstats
import py_compile
import pydoc
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 2b48ea6..ab60a56 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -27,15 +27,13 @@ In ast.c, syntax errors are raised by calling ast_error().
Errors from set_context():
-TODO(jhylton): "assignment to None" is inconsistent with other messages
-
>>> obj.None = 1
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[1]>, line 1)
+SyntaxError: invalid syntax
>>> None = 1
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[2]>, line 1)
+SyntaxError: assignment to keyword (<doctest test.test_syntax[2]>, line 1)
It's a syntax error to assign to the empty tuple. Why isn't it an
error to assign to the empty list? It will always raise some error at
@@ -95,7 +93,7 @@ From compiler_complex_args():
>>> def f(None=1):
... pass
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[14]>, line 1)
+SyntaxError: invalid syntax
From ast_for_arguments():
@@ -108,17 +106,17 @@ SyntaxError: non-default argument follows default argument (<doctest test.test_s
>>> def f(x, None):
... pass
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[16]>, line 1)
+SyntaxError: invalid syntax
>>> def f(*None):
... pass
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[17]>, line 1)
+SyntaxError: invalid syntax
>>> def f(**None):
... pass
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[18]>, line 1)
+SyntaxError: invalid syntax
From ast_for_funcdef():
@@ -126,7 +124,7 @@ From ast_for_funcdef():
>>> def None(x):
... pass
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[19]>, line 1)
+SyntaxError: invalid syntax
From ast_for_call():
@@ -231,7 +229,7 @@ Traceback (most recent call last):
SyntaxError: augmented assignment to generator expression not possible (<doctest test.test_syntax[31]>, line 1)
>>> None += 1
Traceback (most recent call last):
-SyntaxError: assignment to None (<doctest test.test_syntax[32]>, line 1)
+SyntaxError: assignment to keyword (<doctest test.test_syntax[32]>, line 1)
>>> f() += 1
Traceback (most recent call last):
SyntaxError: illegal expression for augmented assignment (<doctest test.test_syntax[33]>, line 1)
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 8862661..b038ff4 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -63,47 +63,6 @@ class SysModuleTest(unittest.TestCase):
# FIXME: testing the code for a lost or replaced excepthook in
# Python/pythonrun.c::PyErr_PrintEx() is tricky.
- def test_exc_clear(self):
- self.assertRaises(TypeError, sys.exc_clear, 42)
-
- # Verify that exc_info is present and matches exc, then clear it, and
- # check that it worked.
- def clear_check(exc):
- typ, value, traceback = sys.exc_info()
- self.assert_(typ is not None)
- self.assert_(value is exc)
- self.assert_(traceback is not None)
-
- sys.exc_clear()
-
- typ, value, traceback = sys.exc_info()
- self.assert_(typ is None)
- self.assert_(value is None)
- self.assert_(traceback is None)
-
- def clear():
- try:
- raise ValueError, 42
- except ValueError as exc:
- clear_check(exc)
-
- # Raise an exception and check that it can be cleared
- clear()
-
- # Verify that a frame currently handling an exception is
- # unaffected by calling exc_clear in a nested frame.
- try:
- raise ValueError, 13
- except ValueError as exc:
- typ1, value1, traceback1 = sys.exc_info()
- clear()
- typ2, value2, traceback2 = sys.exc_info()
-
- self.assert_(typ1 is typ2)
- self.assert_(value1 is exc)
- self.assert_(value1 is value2)
- self.assert_(traceback1 is traceback2)
-
def test_exit(self):
self.assertRaises(TypeError, sys.exit, 42, 42)
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 312050b..636a45e 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -1,4 +1,4 @@
-# encoding: iso8859-1
+# -*- coding: iso-8859-15 -*-
import sys
import os
@@ -372,9 +372,9 @@ class LongnameTest(ReadTest):
def test_read_longname(self):
# Test reading of longname (bug #1471427).
- name = self.subdir + "/" + "123/" * 125 + "longname"
+ longname = self.subdir + "/" + "123/" * 125 + "longname"
try:
- tarinfo = self.tar.getmember(name)
+ tarinfo = self.tar.getmember(longname)
except KeyError:
self.fail("longname not found")
self.assert_(tarinfo.type != tarfile.DIRTYPE, "read longname as dirtype")
@@ -393,13 +393,24 @@ class LongnameTest(ReadTest):
tarinfo = self.tar.getmember(longname)
offset = tarinfo.offset
self.tar.fileobj.seek(offset)
- fobj = StringIO.StringIO(self.tar.fileobj.read(1536))
+ fobj = StringIO.StringIO(self.tar.fileobj.read(3 * 512))
self.assertRaises(tarfile.ReadError, tarfile.open, name="foo.tar", fileobj=fobj)
+ def test_header_offset(self):
+ # Test if the start offset of the TarInfo object includes
+ # the preceding extended header.
+ longname = self.subdir + "/" + "123/" * 125 + "longname"
+ offset = self.tar.getmember(longname).offset
+ fobj = open(tarname)
+ fobj.seek(offset)
+ tarinfo = tarfile.TarInfo.frombuf(fobj.read(512))
+ self.assertEqual(tarinfo.type, self.longnametype)
+
class GNUReadTest(LongnameTest):
subdir = "gnu"
+ longnametype = tarfile.GNUTYPE_LONGNAME
def test_sparse_file(self):
tarinfo1 = self.tar.getmember("ustar/sparse")
@@ -410,26 +421,40 @@ class GNUReadTest(LongnameTest):
"sparse file extraction failed")
-class PaxReadTest(ReadTest):
+class PaxReadTest(LongnameTest):
subdir = "pax"
+ longnametype = tarfile.XHDTYPE
- def test_pax_globheaders(self):
+ def test_pax_global_headers(self):
tar = tarfile.open(tarname, encoding="iso8859-1")
+
tarinfo = tar.getmember("pax/regtype1")
self.assertEqual(tarinfo.uname, "foo")
self.assertEqual(tarinfo.gname, "bar")
- self.assertEqual(tarinfo.pax_headers.get("VENDOR.umlauts"), "ÄÖÜäöüß")
+ self.assertEqual(tarinfo.pax_headers.get("VENDOR.umlauts"), u"ÄÖÜäöüß")
tarinfo = tar.getmember("pax/regtype2")
self.assertEqual(tarinfo.uname, "")
self.assertEqual(tarinfo.gname, "bar")
- self.assertEqual(tarinfo.pax_headers.get("VENDOR.umlauts"), "ÄÖÜäöüß")
+ self.assertEqual(tarinfo.pax_headers.get("VENDOR.umlauts"), u"ÄÖÜäöüß")
tarinfo = tar.getmember("pax/regtype3")
self.assertEqual(tarinfo.uname, "tarfile")
self.assertEqual(tarinfo.gname, "tarfile")
- self.assertEqual(tarinfo.pax_headers.get("VENDOR.umlauts"), "ÄÖÜäöüß")
+ self.assertEqual(tarinfo.pax_headers.get("VENDOR.umlauts"), u"ÄÖÜäöüß")
+
+ def test_pax_number_fields(self):
+ # All following number fields are read from the pax header.
+ tar = tarfile.open(tarname, encoding="iso8859-1")
+ tarinfo = tar.getmember("pax/regtype4")
+ self.assertEqual(tarinfo.size, 7011)
+ self.assertEqual(tarinfo.uid, 123)
+ self.assertEqual(tarinfo.gid, 123)
+ self.assertEqual(tarinfo.mtime, 1041808783.0)
+ self.assertEqual(type(tarinfo.mtime), float)
+ self.assertEqual(float(tarinfo.pax_headers["atime"]), 1041808783.0)
+ self.assertEqual(float(tarinfo.pax_headers["ctime"]), 1041808783.0)
class WriteTest(unittest.TestCase):
@@ -700,68 +725,160 @@ class PaxWriteTest(GNUWriteTest):
n = tar.getmembers()[0].name
self.assert_(name == n, "PAX longname creation failed")
- def test_iso8859_15_filename(self):
- self._test_unicode_filename("iso8859-15")
+ def test_pax_global_header(self):
+ pax_headers = {
+ u"foo": u"bar",
+ u"uid": u"0",
+ u"mtime": u"1.23",
+ u"test": u"äöü",
+ u"äöü": u"test"}
+
+ tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, \
+ pax_headers=pax_headers)
+ tar.addfile(tarfile.TarInfo("test"))
+ tar.close()
+
+ # Test if the global header was written correctly.
+ tar = tarfile.open(tmpname, encoding="iso8859-1")
+ self.assertEqual(tar.pax_headers, pax_headers)
+ self.assertEqual(tar.getmembers()[0].pax_headers, pax_headers)
+
+ # Test if all the fields are unicode.
+ for key, val in tar.pax_headers.items():
+ self.assert_(type(key) is unicode)
+ self.assert_(type(val) is unicode)
+ if key in tarfile.PAX_NUMBER_FIELDS:
+ try:
+ tarfile.PAX_NUMBER_FIELDS[key](val)
+ except (TypeError, ValueError):
+ self.fail("unable to convert pax header field")
+
+ def test_pax_extended_header(self):
+ # The fields from the pax header have priority over the
+ # TarInfo.
+ pax_headers = {u"path": u"foo", u"uid": u"123"}
+
+ tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, encoding="iso8859-1")
+ t = tarfile.TarInfo()
+ t.name = u"äöü" # non-ASCII
+ t.uid = 8**8 # too large
+ t.pax_headers = pax_headers
+ tar.addfile(t)
+ tar.close()
+
+ tar = tarfile.open(tmpname, encoding="iso8859-1")
+ t = tar.getmembers()[0]
+ self.assertEqual(t.pax_headers, pax_headers)
+ self.assertEqual(t.name, "foo")
+ self.assertEqual(t.uid, 123)
+
+
+class UstarUnicodeTest(unittest.TestCase):
+ # All *UnicodeTests FIXME
+
+ format = tarfile.USTAR_FORMAT
+
+ def test_iso8859_1_filename(self):
+ self._test_unicode_filename("iso8859-1")
+
+ def test_utf7_filename(self):
+ self._test_unicode_filename("utf7")
def test_utf8_filename(self):
self._test_unicode_filename("utf8")
- def test_utf16_filename(self):
- self._test_unicode_filename("utf16")
-
def _test_unicode_filename(self, encoding):
- tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT)
- name = "\u20ac".encode(encoding) # Euro sign
- tar.encoding = encoding
+ tar = tarfile.open(tmpname, "w", format=self.format, encoding=encoding, errors="strict")
+ name = "äöü"
tar.addfile(tarfile.TarInfo(name))
tar.close()
tar = tarfile.open(tmpname, encoding=encoding)
- self.assertEqual(tar.getmembers()[0].name, name)
+ self.assert_(type(tar.getnames()[0]) is not unicode)
+ self.assertEqual(tar.getmembers()[0].name, name.encode(encoding))
tar.close()
def test_unicode_filename_error(self):
- # The euro sign filename cannot be translated to iso8859-1 encoding.
- tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, encoding="utf8")
- name = "\u20ac".encode("utf8") # Euro sign
- tar.addfile(tarfile.TarInfo(name))
+ tar = tarfile.open(tmpname, "w", format=self.format, encoding="ascii", errors="strict")
+ tarinfo = tarfile.TarInfo()
+
+ tarinfo.name = "äöü"
+ if self.format == tarfile.PAX_FORMAT:
+ self.assertRaises(UnicodeError, tar.addfile, tarinfo)
+ else:
+ tar.addfile(tarinfo)
+
+ tarinfo.name = u"äöü"
+ self.assertRaises(UnicodeError, tar.addfile, tarinfo)
+
+ tarinfo.name = "foo"
+ tarinfo.uname = u"äöü"
+ self.assertRaises(UnicodeError, tar.addfile, tarinfo)
+
+ def test_unicode_argument(self):
+ tar = tarfile.open(tarname, "r", encoding="iso8859-1", errors="strict")
+ for t in tar:
+ self.assert_(type(t.name) is str)
+ self.assert_(type(t.linkname) is str)
+ self.assert_(type(t.uname) is str)
+ self.assert_(type(t.gname) is str)
tar.close()
- self.assertRaises(UnicodeError, tarfile.open, tmpname, encoding="iso8859-1")
+ def test_uname_unicode(self):
+ for name in (u"äöü", "äöü"):
+ t = tarfile.TarInfo("foo")
+ t.uname = name
+ t.gname = name
- def test_pax_headers(self):
- self._test_pax_headers({"foo": "bar", "uid": 0, "mtime": 1.23})
+ fobj = StringIO.StringIO()
+ tar = tarfile.open("foo.tar", mode="w", fileobj=fobj, format=self.format, encoding="iso8859-1")
+ tar.addfile(t)
+ tar.close()
+ fobj.seek(0)
- self._test_pax_headers({"euro": "\u20ac".encode("utf8")})
+ tar = tarfile.open("foo.tar", fileobj=fobj, encoding="iso8859-1")
+ t = tar.getmember("foo")
+ self.assertEqual(t.uname, "äöü")
+ self.assertEqual(t.gname, "äöü")
- self._test_pax_headers({"euro": "\u20ac"},
- {"euro": "\u20ac".encode("utf8")})
+class GNUUnicodeTest(UstarUnicodeTest):
- self._test_pax_headers({"\u20ac": "euro"},
- {"\u20ac".encode("utf8"): "euro"})
+ format = tarfile.GNU_FORMAT
- def _test_pax_headers(self, pax_headers, cmp_headers=None):
- if cmp_headers is None:
- cmp_headers = pax_headers
- tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT, \
- pax_headers=pax_headers, encoding="utf8")
- tar.addfile(tarfile.TarInfo("test"))
- tar.close()
+class PaxUnicodeTest(UstarUnicodeTest):
- tar = tarfile.open(tmpname, encoding="utf8")
- self.assertEqual(tar.pax_headers, cmp_headers)
+ format = tarfile.PAX_FORMAT
- def test_truncated_header(self):
- tar = tarfile.open(tmpname, "w", format=tarfile.PAX_FORMAT)
- tarinfo = tarfile.TarInfo("123/" * 126 + "longname")
- tar.addfile(tarinfo)
+ def _create_unicode_name(self, name):
+ tar = tarfile.open(tmpname, "w", format=self.format)
+ t = tarfile.TarInfo()
+ t.pax_headers["path"] = name
+ tar.addfile(t)
tar.close()
- # Simulate a premature EOF.
- open(tmpname, "rb+").truncate(1536)
- tar = tarfile.open(tmpname)
- self.assertEqual(tar.getmembers(), [])
+ def test_error_handlers(self):
+ # Test if the unicode error handlers work correctly for characters
+ # that cannot be expressed in a given encoding.
+ self._create_unicode_name(u"äöü")
+
+ for handler, name in (("utf-8", u"äöü".encode("utf8")),
+ ("replace", "???"), ("ignore", "")):
+ tar = tarfile.open(tmpname, format=self.format, encoding="ascii",
+ errors=handler)
+ self.assertEqual(tar.getnames()[0], name)
+
+ self.assertRaises(UnicodeError, tarfile.open, tmpname,
+ encoding="ascii", errors="strict")
+
+ def test_error_handler_utf8(self):
+ # Create a pathname that has one component representable using
+ # iso8859-1 and the other only in iso8859-15.
+ self._create_unicode_name(u"äöü/¤")
+
+ tar = tarfile.open(tmpname, format=self.format, encoding="iso8859-1",
+ errors="utf-8")
+ self.assertEqual(tar.getnames()[0], "äöü/" + u"¤".encode("utf8"))
class AppendTest(unittest.TestCase):
@@ -836,63 +953,58 @@ class LimitsTest(unittest.TestCase):
def test_ustar_limits(self):
# 100 char name
tarinfo = tarfile.TarInfo("0123456789" * 10)
- tarinfo.create_ustar_header()
+ tarinfo.tobuf(tarfile.USTAR_FORMAT)
# 101 char name that cannot be stored
tarinfo = tarfile.TarInfo("0123456789" * 10 + "0")
- self.assertRaises(ValueError, tarinfo.create_ustar_header)
+ self.assertRaises(ValueError, tarinfo.tobuf, tarfile.USTAR_FORMAT)
# 256 char name with a slash at pos 156
tarinfo = tarfile.TarInfo("123/" * 62 + "longname")
- tarinfo.create_ustar_header()
+ tarinfo.tobuf(tarfile.USTAR_FORMAT)
# 256 char name that cannot be stored
tarinfo = tarfile.TarInfo("1234567/" * 31 + "longname")
- self.assertRaises(ValueError, tarinfo.create_ustar_header)
+ self.assertRaises(ValueError, tarinfo.tobuf, tarfile.USTAR_FORMAT)
# 512 char name
tarinfo = tarfile.TarInfo("123/" * 126 + "longname")
- self.assertRaises(ValueError, tarinfo.create_ustar_header)
+ self.assertRaises(ValueError, tarinfo.tobuf, tarfile.USTAR_FORMAT)
# 512 char linkname
tarinfo = tarfile.TarInfo("longlink")
tarinfo.linkname = "123/" * 126 + "longname"
- self.assertRaises(ValueError, tarinfo.create_ustar_header)
+ self.assertRaises(ValueError, tarinfo.tobuf, tarfile.USTAR_FORMAT)
# uid > 8 digits
tarinfo = tarfile.TarInfo("name")
tarinfo.uid = 010000000
- self.assertRaises(ValueError, tarinfo.create_ustar_header)
+ self.assertRaises(ValueError, tarinfo.tobuf, tarfile.USTAR_FORMAT)
def test_gnu_limits(self):
tarinfo = tarfile.TarInfo("123/" * 126 + "longname")
- tarinfo.create_gnu_header()
+ tarinfo.tobuf(tarfile.GNU_FORMAT)
tarinfo = tarfile.TarInfo("longlink")
tarinfo.linkname = "123/" * 126 + "longname"
- tarinfo.create_gnu_header()
+ tarinfo.tobuf(tarfile.GNU_FORMAT)
# uid >= 256 ** 7
tarinfo = tarfile.TarInfo("name")
tarinfo.uid = 04000000000000000000
- self.assertRaises(ValueError, tarinfo.create_gnu_header)
+ self.assertRaises(ValueError, tarinfo.tobuf, tarfile.GNU_FORMAT)
def test_pax_limits(self):
- # A 256 char name that can be stored without an extended header.
- tarinfo = tarfile.TarInfo("123/" * 62 + "longname")
- self.assert_(len(tarinfo.create_pax_header("utf8")) == 512,
- "create_pax_header attached superfluous extended header")
-
tarinfo = tarfile.TarInfo("123/" * 126 + "longname")
- tarinfo.create_pax_header("utf8")
+ tarinfo.tobuf(tarfile.PAX_FORMAT)
tarinfo = tarfile.TarInfo("longlink")
tarinfo.linkname = "123/" * 126 + "longname"
- tarinfo.create_pax_header("utf8")
+ tarinfo.tobuf(tarfile.PAX_FORMAT)
tarinfo = tarfile.TarInfo("name")
tarinfo.uid = 04000000000000000000
- tarinfo.create_pax_header("utf8")
+ tarinfo.tobuf(tarfile.PAX_FORMAT)
class GzipMiscReadTest(MiscReadTest):
@@ -940,6 +1052,9 @@ def test_main():
StreamWriteTest,
GNUWriteTest,
PaxWriteTest,
+ UstarUnicodeTest,
+ GNUUnicodeTest,
+ PaxUnicodeTest,
AppendTest,
LimitsTest,
]
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
index 0880f0f..7e1708e 100644
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -19,7 +19,7 @@ whether the line contains the completion of a statement.
>>> dump_tokens("if False:\\n"
... " # NL\\n"
-... " True = False # NEWLINE\\n")
+... " a = False # NEWLINE\\n")
NAME 'if' (1, 0) (1, 2)
NAME 'False' (1, 3) (1, 8)
OP ':' (1, 8) (1, 9)
@@ -27,7 +27,7 @@ NEWLINE '\\n' (1, 9) (1, 10)
COMMENT '# NL' (2, 4) (2, 8)
NL '\\n' (2, 8) (2, 9)
INDENT ' ' (3, 0) (3, 4)
-NAME 'True' (3, 4) (3, 8)
+NAME 'a' (3, 4) (3, 5)
OP '=' (3, 9) (3, 10)
NAME 'False' (3, 11) (3, 16)
COMMENT '# NEWLINE' (3, 17) (3, 26)
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 1b9e2f8..98d3beb 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -52,58 +52,13 @@ class TracebackCases(unittest.TestCase):
self.assert_("^" in err[2])
self.assert_(err[1].find(")") == err[2].find("^"))
- def test_bug737473(self):
- import sys, os, tempfile, time
-
- savedpath = sys.path[:]
- testdir = tempfile.mkdtemp()
- try:
- sys.path.insert(0, testdir)
- testfile = os.path.join(testdir, 'test_bug737473.py')
- print("""
-def test():
- raise ValueError""", file=open(testfile, 'w'))
-
- if 'test_bug737473' in sys.modules:
- del sys.modules['test_bug737473']
- import test_bug737473
-
- try:
- test_bug737473.test()
- except ValueError:
- # this loads source code to linecache
- traceback.extract_tb(sys.exc_traceback)
-
- # If this test runs too quickly, test_bug737473.py's mtime
- # attribute will remain unchanged even if the file is rewritten.
- # Consequently, the file would not reload. So, added a sleep()
- # delay to assure that a new, distinct timestamp is written.
- # Since WinME with FAT32 has multisecond resolution, more than
- # three seconds are needed for this test to pass reliably :-(
- time.sleep(4)
-
- print("""
-def test():
- raise NotImplementedError""", file=open(testfile, 'w'))
- reload(test_bug737473)
- try:
- test_bug737473.test()
- except NotImplementedError:
- src = traceback.extract_tb(sys.exc_traceback)[-1][-1]
- self.failUnlessEqual(src, 'raise NotImplementedError')
- finally:
- sys.path[:] = savedpath
- for f in os.listdir(testdir):
- os.unlink(os.path.join(testdir, f))
- os.rmdir(testdir)
-
def test_members(self):
# Covers Python/structmember.c::listmembers()
try:
1/0
except:
import sys
- sys.exc_traceback.__members__
+ sys.exc_info()[2].__members__
def test_base_exception(self):
# Test that exceptions derived from BaseException are formatted right
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index a62afde..7a3f207 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -8,6 +8,10 @@ import os
import mimetools
import tempfile
import StringIO
+import ftplib
+import threading
+import socket
+import time
def hexescape(char):
"""Escape char as RFC 2396 specifies"""
@@ -541,6 +545,76 @@ class Pathname_Tests(unittest.TestCase):
"url2pathname() failed; %s != %s" %
(expect, result))
+# Just commented them out.
+# Can't really tell why keep failing in windows and sparc.
+# Everywhere else they work ok, but on those machines, someteimes
+# fail in one of the tests, sometimes in other. I have a linux, and
+# the tests go ok.
+# If anybody has one of the problematic enviroments, please help!
+# . Facundo
+#
+# def server(evt):
+# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+# serv.settimeout(3)
+# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+# serv.bind(("", 9093))
+# serv.listen(5)
+# try:
+# conn, addr = serv.accept()
+# conn.send("1 Hola mundo\n")
+# cantdata = 0
+# while cantdata < 13:
+# data = conn.recv(13-cantdata)
+# cantdata += len(data)
+# time.sleep(.3)
+# conn.send("2 No more lines\n")
+# conn.close()
+# except socket.timeout:
+# pass
+# finally:
+# serv.close()
+# evt.set()
+#
+# class FTPWrapperTests(unittest.TestCase):
+#
+# def setUp(self):
+# ftplib.FTP.port = 9093
+# self.evt = threading.Event()
+# threading.Thread(target=server, args=(self.evt,)).start()
+# time.sleep(.1)
+#
+# def tearDown(self):
+# self.evt.wait()
+#
+# def testBasic(self):
+# # connects
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# ftp.ftp.sock.close()
+#
+# def testTimeoutDefault(self):
+# # default
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# self.assertTrue(ftp.ftp.sock.gettimeout() is None)
+# ftp.ftp.sock.close()
+#
+# def testTimeoutValue(self):
+# # a value
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], timeout=30)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.ftp.sock.close()
+#
+# def testTimeoutNone(self):
+# # None, having other default
+# previous = socket.getdefaulttimeout()
+# socket.setdefaulttimeout(30)
+# try:
+# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])
+# finally:
+# socket.setdefaulttimeout(previous)
+# self.assertEqual(ftp.ftp.sock.gettimeout(), 30)
+# ftp.ftp.close()
+#
+
def test_main():
@@ -551,7 +625,8 @@ def test_main():
QuotingTests,
UnquotingTests,
urlencode_Tests,
- Pathname_Tests
+ Pathname_Tests,
+ #FTPWrapperTests,
)
diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
index 76ec018..1bf6294 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -17,7 +17,7 @@ alist = [{'astring': 'foo@bar.baz.spam',
'ashortlong': 2,
'anotherlist': ['.zyx.41'],
'abase64': xmlrpclib.Binary("my dog has fleas"),
- 'boolean': xmlrpclib.False,
+ 'boolean': False,
'unicode': '\u4000\u6000\u8000',
'ukey\u4000': 'regular value',
'datetime1': xmlrpclib.DateTime('20050210T11:41:23'),
@@ -133,10 +133,11 @@ class XMLRPCTestCase(unittest.TestCase):
"""
# sys.setdefaultencoding() normally doesn't exist after site.py is
- # loaded. reload(sys) is the way to get it back.
+ # loaded. Re-initializing sys again is the way to get it back. :-(
old_encoding = sys.getdefaultencoding()
setdefaultencoding_existed = hasattr(sys, "setdefaultencoding")
- reload(sys) # ugh!
+ import imp
+ imp.init_builtin('sys')
sys.setdefaultencoding("iso-8859-1")
try:
(s, d), m = xmlrpclib.loads(utf8)
diff --git a/Lib/test/testtar.tar b/Lib/test/testtar.tar
index c4c82b8..3529bdf 100644
--- a/Lib/test/testtar.tar
+++ b/Lib/test/testtar.tar
Binary files differ
diff --git a/Lib/textwrap.py b/Lib/textwrap.py
index e65cdc3..22a6252 100644
--- a/Lib/textwrap.py
+++ b/Lib/textwrap.py
@@ -9,14 +9,6 @@ __revision__ = "$Id$"
import string, re
-# Do the right thing with boolean values for all known Python versions
-# (so this module can be copied to projects that don't depend on Python
-# 2.3, e.g. Optik and Docutils).
-try:
- True, False
-except NameError:
- (True, False) = (1, 0)
-
__all__ = ['TextWrapper', 'wrap', 'fill']
# Hardcode the recognized whitespace characters to the US-ASCII
diff --git a/Lib/unittest.py b/Lib/unittest.py
index 46e2854..6ede5ad 100644
--- a/Lib/unittest.py
+++ b/Lib/unittest.py
@@ -65,22 +65,6 @@ __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
##############################################################################
-# Backward compatibility
-##############################################################################
-if sys.version_info[:2] < (2, 2):
- False, True = 0, 1
- def isinstance(obj, clsinfo):
- import __builtin__
- if type(clsinfo) in (tuple, list):
- for cls in clsinfo:
- if cls is type: cls = types.ClassType
- if __builtin__.isinstance(obj, cls):
- return 1
- return 0
- else: return __builtin__.isinstance(obj, clsinfo)
-
-
-##############################################################################
# Test framework core
##############################################################################
diff --git a/Lib/urllib.py b/Lib/urllib.py
index 6a7c23f..c6bd87f 100644
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -805,19 +805,20 @@ def noheaders():
class ftpwrapper:
"""Class used by open_ftp() for cache of open FTP connections."""
- def __init__(self, user, passwd, host, port, dirs):
+ def __init__(self, user, passwd, host, port, dirs, timeout=None):
self.user = user
self.passwd = passwd
self.host = host
self.port = port
self.dirs = dirs
+ self.timeout = timeout
self.init()
def init(self):
import ftplib
self.busy = 0
self.ftp = ftplib.FTP()
- self.ftp.connect(self.host, self.port)
+ self.ftp.connect(self.host, self.port, self.timeout)
self.ftp.login(self.user, self.passwd)
for dir in self.dirs:
self.ftp.cwd(dir)
diff --git a/Lib/uuid.py b/Lib/uuid.py
index 029df51..89fc83c 100644
--- a/Lib/uuid.py
+++ b/Lib/uuid.py
@@ -535,8 +535,8 @@ def uuid1(node=None, clock_seq=None):
def uuid3(namespace, name):
"""Generate a UUID from the MD5 hash of a namespace UUID and a name."""
- import hashlib
- hash = hashlib.md5(namespace.bytes + name).digest()
+ from hashlib import md5
+ hash = md5(namespace.bytes + name).digest()
return UUID(bytes=hash[:16], version=3)
def uuid4():
@@ -558,8 +558,8 @@ def uuid4():
def uuid5(namespace, name):
"""Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
- import sha
- hash = sha.sha(namespace.bytes + name).digest()
+ from hashlib import sha1
+ hash = sha1(namespace.bytes + name).digest()
return UUID(bytes=hash[:16], version=5)
# The following standard UUIDs are for use with uuid3() or uuid5().
diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py
index fb81bf3..00c6181 100644
--- a/Lib/wsgiref/handlers.py
+++ b/Lib/wsgiref/handlers.py
@@ -8,23 +8,6 @@ import sys, os, time
__all__ = ['BaseHandler', 'SimpleHandler', 'BaseCGIHandler', 'CGIHandler']
-try:
- dict
-except NameError:
- def dict(items):
- d = {}
- for k,v in items:
- d[k] = v
- return d
-
-try:
- True
- False
-except NameError:
- True = not None
- False = not True
-
-
# Weekday and month names for HTTP date/time formatting; always English!
_weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
_monthname = [None, # Dummy so we can use 1-based month numbers
diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py
index f0e4f8f..2b5ed6e 100644
--- a/Lib/xmlrpclib.py
+++ b/Lib/xmlrpclib.py
@@ -274,8 +274,6 @@ class Fault(Error):
# all other values are interpreted as False.
boolean = Boolean = bool
-# to avoid breaking code which references xmlrpclib.{True,False}
-True, False = True, False
##
# Wrapper for XML-RPC DateTime values. This converts a time value to