summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ConfigParser.py15
-rw-r--r--Lib/Queue.py2
-rw-r--r--Lib/SimpleXMLRPCServer.py6
-rw-r--r--Lib/_strptime.py2
-rw-r--r--Lib/atexit.py3
-rwxr-xr-xLib/base64.py2
-rw-r--r--Lib/bsddb/test/test_dbobj.py4
-rwxr-xr-xLib/cgi.py6
-rw-r--r--Lib/codecs.py33
-rw-r--r--Lib/colorsys.py3
-rw-r--r--Lib/compiler/pycodegen.py12
-rw-r--r--Lib/ctypes/__init__.py2
-rw-r--r--Lib/ctypes/test/__init__.py3
-rw-r--r--Lib/ctypes/test/test_bitfields.py9
-rw-r--r--Lib/ctypes/test/test_callbacks.py13
-rw-r--r--Lib/ctypes/test/test_cast.py16
-rw-r--r--Lib/ctypes/test/test_structures.py30
-rw-r--r--Lib/ctypes/test/test_win32.py3
-rw-r--r--Lib/decimal.py67
-rw-r--r--Lib/distutils/command/bdist_rpm.py67
-rw-r--r--Lib/distutils/command/build_ext.py2
-rw-r--r--Lib/distutils/command/install_egg_info.py3
-rw-r--r--Lib/distutils/command/register.py2
-rw-r--r--Lib/distutils/command/wininst-8.exebin0 -> 61440 bytes
-rw-r--r--Lib/distutils/sysconfig.py5
-rw-r--r--Lib/distutils/unixccompiler.py16
-rw-r--r--Lib/email/utils.py4
-rw-r--r--Lib/encodings/__init__.py6
-rw-r--r--Lib/encodings/bz2_codec.py29
-rw-r--r--Lib/encodings/utf_8_sig.py2
-rw-r--r--Lib/encodings/zlib_codec.py30
-rw-r--r--Lib/ftplib.py11
-rw-r--r--Lib/functools.py4
-rw-r--r--Lib/genericpath.py77
-rw-r--r--Lib/gzip.py7
-rw-r--r--Lib/hashlib.py31
-rw-r--r--Lib/httplib.py26
-rw-r--r--Lib/idlelib/CodeContext.py77
-rw-r--r--Lib/idlelib/EditorWindow.py2
-rw-r--r--Lib/idlelib/NEWS.txt7
-rw-r--r--Lib/idlelib/PyShell.py4
-rw-r--r--Lib/idlelib/ScriptBinding.py10
-rw-r--r--Lib/inspect.py38
-rwxr-xr-xLib/lib-tk/Tix.py5
-rw-r--r--Lib/lib-tk/Tkinter.py3
-rw-r--r--Lib/lib-tk/tkMessageBox.py10
-rw-r--r--Lib/lib-tk/tkSimpleDialog.py14
-rw-r--r--Lib/lib-tk/turtle.py2
-rw-r--r--Lib/logging/__init__.py9
-rw-r--r--Lib/logging/config.py11
-rw-r--r--Lib/logging/handlers.py4
-rw-r--r--Lib/macpath.py63
-rwxr-xr-xLib/mailbox.py99
-rw-r--r--Lib/ntpath.py77
-rw-r--r--Lib/os.py8
-rw-r--r--Lib/os2emxpath.py276
-rwxr-xr-xLib/pdb.py2
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py2
-rw-r--r--Lib/plat-sunos5/STROPTS.py2
-rw-r--r--Lib/posixpath.py87
-rw-r--r--Lib/pstats.py2
-rw-r--r--Lib/pty.py4
-rw-r--r--Lib/pyclbr.py2
-rw-r--r--Lib/sgmllib.py19
-rwxr-xr-xLib/smtplib.py39
-rw-r--r--Lib/subprocess.py14
-rw-r--r--Lib/tarfile.py179
-rw-r--r--Lib/test/README4
-rw-r--r--Lib/test/crashers/bogus_sre_bytecode.py47
-rw-r--r--Lib/test/crashers/infinite_loop_re.py16
-rw-r--r--Lib/test/crashers/loosing_mro_ref.py36
-rw-r--r--Lib/test/list_tests.py3
-rw-r--r--Lib/test/output/test_MimeWriter110
-rw-r--r--Lib/test/output/test_cgi42
-rw-r--r--Lib/test/output/test_cookie32
-rw-r--r--Lib/test/output/test_global5
-rw-r--r--Lib/test/output/test_grammar69
-rw-r--r--Lib/test/output/test_httplib13
-rw-r--r--Lib/test/output/test_math28
-rw-r--r--Lib/test/output/test_mmap38
-rw-r--r--Lib/test/output/test_nis2
-rw-r--r--Lib/test/output/test_opcodes6
-rw-r--r--Lib/test/output/test_openpty2
-rw-r--r--Lib/test/output/test_poll19
-rw-r--r--Lib/test/output/test_regex29
-rw-r--r--Lib/test/output/test_scope24
-rw-r--r--Lib/test/output/test_tokenize75
-rw-r--r--Lib/test/output/test_types15
-rw-r--r--Lib/test/output/test_xdrlib19
-rw-r--r--Lib/test/outstanding_bugs.py15
-rw-r--r--Lib/test/sgml_input.html212
-rw-r--r--Lib/test/string_tests.py2
-rw-r--r--Lib/test/test_MimeWriter.py249
-rw-r--r--Lib/test/test_StringIO.py23
-rw-r--r--Lib/test/test___future__.py108
-rwxr-xr-xLib/test/test_array.py7
-rwxr-xr-xLib/test/test_binascii.py2
-rw-r--r--Lib/test/test_bufio.py116
-rw-r--r--Lib/test/test_builtin.py17
-rw-r--r--Lib/test/test_cfgparser.py46
-rw-r--r--Lib/test/test_cgi.py260
-rw-r--r--Lib/test/test_class.py8
-rw-r--r--Lib/test/test_codecencodings_cn.py2
-rw-r--r--Lib/test/test_codecs.py60
-rw-r--r--Lib/test/test_complex_args.py91
-rw-r--r--Lib/test/test_contextlib.py26
-rw-r--r--Lib/test/test_cookie.py114
-rw-r--r--Lib/test/test_datetime.py1
-rw-r--r--Lib/test/test_decimal.py28
-rw-r--r--Lib/test/test_descr.py14
-rw-r--r--Lib/test/test_dict.py10
-rw-r--r--Lib/test/test_exceptions.py72
-rwxr-xr-xLib/test/test_fcntl.py2
-rw-r--r--Lib/test/test_format.py4
-rw-r--r--Lib/test/test_functools.py7
-rw-r--r--Lib/test/test_future.py21
-rw-r--r--Lib/test/test_genericpath.py184
-rw-r--r--Lib/test/test_global.py50
-rw-r--r--Lib/test/test_grammar.py1681
-rw-r--r--Lib/test/test_gzip.py11
-rw-r--r--Lib/test/test_httplib.py166
-rw-r--r--Lib/test/test_imp.py62
-rw-r--r--Lib/test/test_import.py397
-rw-r--r--Lib/test/test_inspect.py11
-rw-r--r--Lib/test/test_itertools.py5
-rw-r--r--Lib/test/test_long.py23
-rw-r--r--Lib/test/test_mailbox.py55
-rw-r--r--Lib/test/test_math.py435
-rw-r--r--Lib/test/test_mmap.py394
-rw-r--r--Lib/test/test_modulefinder.py11
-rw-r--r--Lib/test/test_multibytecodec.py16
-rw-r--r--Lib/test/test_mutants.py2
-rw-r--r--Lib/test/test_new.py8
-rw-r--r--Lib/test/test_nis.py67
-rw-r--r--Lib/test/test_opcodes.py207
-rw-r--r--Lib/test/test_openpty.py30
-rw-r--r--Lib/test/test_os.py17
-rw-r--r--Lib/test/test_parser.py38
-rw-r--r--Lib/test/test_peepholer.py35
-rw-r--r--Lib/test/test_pep352.py3
-rw-r--r--Lib/test/test_poll.py316
-rw-r--r--Lib/test/test_pyclbr.py3
-rw-r--r--Lib/test/test_scope.py675
-rw-r--r--Lib/test/test_set.py11
-rw-r--r--Lib/test/test_sgmllib.py28
-rw-r--r--Lib/test/test_sha.py19
-rw-r--r--Lib/test/test_structmembers.py80
-rw-r--r--Lib/test/test_subprocess.py6
-rw-r--r--Lib/test/test_support.py6
-rw-r--r--Lib/test/test_syntax.py132
-rw-r--r--Lib/test/test_tarfile.py49
-rw-r--r--Lib/test/test_tempfile.py2
-rw-r--r--Lib/test/test_time.py10
-rw-r--r--Lib/test/test_tokenize.py117
-rw-r--r--Lib/test/test_traceback.py4
-rw-r--r--Lib/test/test_types.py550
-rw-r--r--Lib/test/test_unicode.py3
-rw-r--r--Lib/test/test_xdrlib.py55
-rw-r--r--Lib/test/test_xmlrpc.py9
-rw-r--r--Lib/tokenize.py109
-rw-r--r--Lib/traceback.py5
-rw-r--r--Lib/urllib.py8
-rw-r--r--Lib/urllib2.py4
-rwxr-xr-xLib/uu.py4
-rw-r--r--Lib/webbrowser.py18
-rw-r--r--Lib/xdrlib.py58
-rw-r--r--Lib/xmlrpclib.py21
167 files changed, 5633 insertions, 4352 deletions
diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py
index 6dc53b9..65c8ce5 100644
--- a/Lib/ConfigParser.py
+++ b/Lib/ConfigParser.py
@@ -199,11 +199,11 @@ class MissingSectionHeaderError(ParsingError):
self.line = line
-
class RawConfigParser:
- def __init__(self, defaults=None):
- self._sections = {}
- self._defaults = {}
+ def __init__(self, defaults=None, dict_type=dict):
+ self._dict = dict_type
+ self._sections = self._dict()
+ self._defaults = self._dict()
if defaults:
for key, value in defaults.items():
self._defaults[self.optionxform(key)] = value
@@ -224,7 +224,7 @@ class RawConfigParser:
"""
if section in self._sections:
raise DuplicateSectionError(section)
- self._sections[section] = {}
+ self._sections[section] = self._dict()
def has_section(self, section):
"""Indicate whether the named section is present in the configuration.
@@ -307,7 +307,7 @@ class RawConfigParser:
except KeyError:
if section != DEFAULTSECT:
raise NoSectionError(section)
- d2 = {}
+ d2 = self._dict()
d = self._defaults.copy()
d.update(d2)
if "__name__" in d:
@@ -453,7 +453,8 @@ class RawConfigParser:
elif sectname == DEFAULTSECT:
cursect = self._defaults
else:
- cursect = {'__name__': sectname}
+ cursect = self._dict()
+ cursect['__name__'] = sectname
self._sections[sectname] = cursect
# So sections can't start with a continuation line
optname = None
diff --git a/Lib/Queue.py b/Lib/Queue.py
index 0f80584..79b0abf 100644
--- a/Lib/Queue.py
+++ b/Lib/Queue.py
@@ -26,7 +26,7 @@ class Queue:
self._init(maxsize)
# mutex must be held whenever the queue is mutating. All methods
# that acquire mutex must release it before returning. mutex
- # is shared between the two conditions, so acquiring and
+ # is shared between the three conditions, so acquiring and
# releasing the conditions also acquires and releases mutex.
self.mutex = threading.Lock()
# Notify not_empty whenever an item is added to the queue; a
diff --git a/Lib/SimpleXMLRPCServer.py b/Lib/SimpleXMLRPCServer.py
index 3b0a6a5..c6f6958 100644
--- a/Lib/SimpleXMLRPCServer.py
+++ b/Lib/SimpleXMLRPCServer.py
@@ -264,8 +264,9 @@ class SimpleXMLRPCDispatcher:
encoding=self.encoding)
except:
# report exception back to server
+ exc_type, exc_value, exc_tb = sys.exc_info()
response = xmlrpclib.dumps(
- xmlrpclib.Fault(1, "%s:%s" % sys.exc_info()[:2]),
+ xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)),
encoding=self.encoding, allow_none=self.allow_none,
)
@@ -364,9 +365,10 @@ class SimpleXMLRPCDispatcher:
'faultString' : fault.faultString}
)
except:
+ exc_type, exc_value, exc_tb = sys.exc_info()
results.append(
{'faultCode' : 1,
- 'faultString' : "%s:%s" % sys.exc_info()[:2]}
+ 'faultString' : "%s:%s" % (exc_type, exc_value)}
)
return results
diff --git a/Lib/_strptime.py b/Lib/_strptime.py
index ce8525b..3fb5602 100644
--- a/Lib/_strptime.py
+++ b/Lib/_strptime.py
@@ -306,7 +306,7 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
_cache_lock.release()
found = format_regex.match(data_string)
if not found:
- raise ValueError("time data did not match format: data=%s fmt=%s" %
+ raise ValueError("time data %r does not match format %r" %
(data_string, format))
if len(data_string) != found.end():
raise ValueError("unconverted data remains: %s" %
diff --git a/Lib/atexit.py b/Lib/atexit.py
index c9f4cc6..93fddf7 100644
--- a/Lib/atexit.py
+++ b/Lib/atexit.py
@@ -40,8 +40,11 @@ def register(func, *targs, **kargs):
func - function to be called at exit
targs - optional arguments to pass to func
kargs - optional keyword arguments to pass to func
+
+ func is returned to facilitate usage as a decorator.
"""
_exithandlers.append((func, targs, kargs))
+ return func
if hasattr(sys, "exitfunc"):
# Assume it's another registered exit function - append it to our list
diff --git a/Lib/base64.py b/Lib/base64.py
index c196cd8..41a5e14 100755
--- a/Lib/base64.py
+++ b/Lib/base64.py
@@ -308,7 +308,7 @@ def decode(input, output):
def encodestring(s):
- """Encode a string."""
+ """Encode a string into multiple lines of base-64 data."""
pieces = []
for i in range(0, len(s), MAXBINSIZE):
chunk = s[i : i + MAXBINSIZE]
diff --git a/Lib/bsddb/test/test_dbobj.py b/Lib/bsddb/test/test_dbobj.py
index 1305883..bba6a5b 100644
--- a/Lib/bsddb/test/test_dbobj.py
+++ b/Lib/bsddb/test/test_dbobj.py
@@ -69,6 +69,10 @@ class dbobjTestCase(unittest.TestCase):
self.db.close()
self.env.close()
+ def test03_dbobj_type_before_open(self):
+ # Ensure this doesn't cause a segfault.
+ self.assertRaises(db.DBInvalidArgError, db.DB().type)
+
#----------------------------------------------------------------------
def test_suite():
diff --git a/Lib/cgi.py b/Lib/cgi.py
index fa8fd13..80b3b7a 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -799,8 +799,10 @@ class FormContentDict(UserDict.UserDict):
form.dict == {key: [val, val, ...], ...}
"""
- def __init__(self, environ=os.environ):
- self.dict = self.data = parse(environ=environ)
+ def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
+ self.dict = self.data = parse(environ=environ,
+ keep_blank_values=keep_blank_values,
+ strict_parsing=strict_parsing)
self.query_string = environ['QUERY_STRING']
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 1518d75..f834b8d 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -329,6 +329,12 @@ class StreamWriter(Codec):
"""
return getattr(self.stream, name)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
###
class StreamReader(Codec):
@@ -568,6 +574,12 @@ class StreamReader(Codec):
"""
return getattr(self.stream, name)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
###
class StreamReaderWriter:
@@ -641,6 +653,14 @@ class StreamReaderWriter:
"""
return getattr(self.stream, name)
+ # these are needed to make "with codecs.open(...)" work properly
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
###
class StreamRecoder:
@@ -751,6 +771,12 @@ class StreamRecoder:
"""
return getattr(self.stream, name)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
### Shortcuts
def open(filename, mode='rb', encoding=None, errors='strict', buffering=1):
@@ -824,9 +850,10 @@ def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'):
"""
if file_encoding is None:
file_encoding = data_encoding
- info = lookup(data_encoding)
- sr = StreamRecoder(file, info.encode, info.decode,
- info.streamreader, info.streamwriter, errors)
+ data_info = lookup(data_encoding)
+ file_info = lookup(file_encoding)
+ sr = StreamRecoder(file, data_info.encode, data_info.decode,
+ file_info.streamreader, file_info.streamwriter, errors)
# Add attributes to simplify introspection
sr.data_encoding = data_encoding
sr.file_encoding = file_encoding
diff --git a/Lib/colorsys.py b/Lib/colorsys.py
index 39b4b16..851417b 100644
--- a/Lib/colorsys.py
+++ b/Lib/colorsys.py
@@ -117,7 +117,8 @@ def hsv_to_rgb(h, s, v):
p = v*(1.0 - s)
q = v*(1.0 - s*f)
t = v*(1.0 - s*(1.0-f))
- if i%6 == 0: return v, t, p
+ i = i%6
+ if i == 0: return v, t, p
if i == 1: return q, v, p
if i == 2: return p, v, t
if i == 3: return p, q, v
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index b08a307..353c2c9 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -577,12 +577,11 @@ class CodeGenerator:
def visitListComp(self, node):
self.set_lineno(node)
# setup list
- append = "$append%d" % self.__list_count
+ tmpname = "$list%d" % self.__list_count
self.__list_count = self.__list_count + 1
self.emit('BUILD_LIST', 0)
self.emit('DUP_TOP')
- self.emit('LOAD_ATTR', 'append')
- self._implicitNameOp('STORE', append)
+ self._implicitNameOp('STORE', tmpname)
stack = []
for i, for_ in zip(range(len(node.quals)), node.quals):
@@ -594,10 +593,9 @@ class CodeGenerator:
self.visit(if_, cont)
stack.insert(0, (start, cont, anchor))
- self._implicitNameOp('LOAD', append)
+ self._implicitNameOp('LOAD', tmpname)
self.visit(node.expr)
- self.emit('CALL_FUNCTION', 1)
- self.emit('POP_TOP')
+ self.emit('LIST_APPEND')
for start, cont, anchor in stack:
if cont:
@@ -608,7 +606,7 @@ class CodeGenerator:
self.nextBlock(skip_one)
self.emit('JUMP_ABSOLUTE', start)
self.startBlock(anchor)
- self._implicitNameOp('DELETE', append)
+ self._implicitNameOp('DELETE', tmpname)
self.__list_count = self.__list_count - 1
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index 78a2ab8..eb5d97e 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -427,6 +427,8 @@ if sizeof(c_uint) == sizeof(c_void_p):
c_size_t = c_uint
elif sizeof(c_ulong) == sizeof(c_void_p):
c_size_t = c_ulong
+elif sizeof(c_ulonglong) == sizeof(c_void_p):
+ c_size_t = c_ulonglong
# functions
diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py
index 2ae5405..2b745c2 100644
--- a/Lib/ctypes/test/__init__.py
+++ b/Lib/ctypes/test/__init__.py
@@ -37,7 +37,8 @@ def requires(resource, msg=None):
def find_package_modules(package, mask):
import fnmatch
- if hasattr(package, "__loader__"):
+ if (hasattr(package, "__loader__") and
+ hasattr(package.__loader__, '_files')):
path = package.__name__.replace(".", os.path.sep)
mask = os.path.join(path, mask)
for fnm in package.__loader__._files.iterkeys():
diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py
index 92c4669..2867cbf 100644
--- a/Lib/ctypes/test/test_bitfields.py
+++ b/Lib/ctypes/test/test_bitfields.py
@@ -215,5 +215,14 @@ class BitFieldTest(unittest.TestCase):
("b", c_ubyte, 4)]
self.failUnlessEqual(sizeof(X), sizeof(c_byte))
+ def test_anon_bitfields(self):
+ # anonymous bit-fields gave a strange error message
+ class X(Structure):
+ _fields_ = [("a", c_byte, 4),
+ ("b", c_ubyte, 4)]
+ class Y(Structure):
+ _anonymous_ = ["_"]
+ _fields_ = [("_", X)]
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
index 9d96a54..f47fc37 100644
--- a/Lib/ctypes/test/test_callbacks.py
+++ b/Lib/ctypes/test/test_callbacks.py
@@ -101,6 +101,19 @@ class Callbacks(unittest.TestCase):
after = grc(o)
self.failUnlessEqual((after, o), (before, o))
+ def test_unsupported_restype_1(self):
+ # Only "fundamental" result types are supported for callback
+ # functions, the type must have a non-NULL stgdict->setfunc.
+ # POINTER(c_double), for example, is not supported.
+
+ prototype = self.functype.im_func(POINTER(c_double))
+ # The type is checked when the prototype is called
+ self.assertRaises(TypeError, prototype, lambda: None)
+
+ def test_unsupported_restype_2(self):
+ prototype = self.functype.im_func(object)
+ self.assertRaises(TypeError, prototype, lambda: None)
+
try:
WINFUNCTYPE
except NameError:
diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py
index 09e928f..7371b0f 100644
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -57,5 +57,21 @@ class Test(unittest.TestCase):
c_int()
self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+ def test_char_p(self):
+ # This didn't work: bad argument to internal function
+ s = c_char_p("hiho")
+ self.failUnlessEqual(cast(cast(s, c_void_p), c_char_p).value,
+ "hiho")
+
+ try:
+ c_wchar_p
+ except NameError:
+ pass
+ else:
+ def test_wchar_p(self):
+ s = c_wchar_p("hiho")
+ self.failUnlessEqual(cast(cast(s, c_void_p), c_wchar_p).value,
+ "hiho")
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index 8a4531d..613163d 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -381,5 +381,35 @@ class PointerMemberTestCase(unittest.TestCase):
s.p = None
self.failUnlessEqual(s.x, 12345678)
+class TestRecursiveStructure(unittest.TestCase):
+ def test_contains_itself(self):
+ class Recursive(Structure):
+ pass
+
+ try:
+ Recursive._fields_ = [("next", Recursive)]
+ except AttributeError, details:
+ self.failUnless("Structure or union cannot contain itself" in
+ str(details))
+ else:
+ self.fail("Structure or union cannot contain itself")
+
+
+ def test_vice_versa(self):
+ class First(Structure):
+ pass
+ class Second(Structure):
+ pass
+
+ First._fields_ = [("second", Second)]
+
+ try:
+ Second._fields_ = [("first", First)]
+ except AttributeError, details:
+ self.failUnless("_fields_ is final" in
+ str(details))
+ else:
+ self.fail("AttributeError not raised")
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
index db530d3..10deaca 100644
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -6,7 +6,8 @@ import unittest, sys
import _ctypes_test
-if sys.platform == "win32":
+if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
+ # Only windows 32-bit has different calling conventions.
class WindowsTestCase(unittest.TestCase):
def test_callconv_1(self):
diff --git a/Lib/decimal.py b/Lib/decimal.py
index 2f2a617..86455f3 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -131,7 +131,7 @@ __all__ = [
'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
# Functions for manipulating contexts
- 'setcontext', 'getcontext'
+ 'setcontext', 'getcontext', 'localcontext'
]
import copy as _copy
@@ -458,6 +458,49 @@ else:
del threading, local # Don't contaminate the namespace
+def localcontext(ctx=None):
+ """Return a context manager for a copy of the supplied context
+
+ Uses a copy of the current context if no context is specified
+ The returned context manager creates a local decimal context
+ in a with statement:
+ def sin(x):
+ with localcontext() as ctx:
+ ctx.prec += 2
+ # Rest of sin calculation algorithm
+ # uses a precision 2 greater than normal
+ return +s # Convert result to normal precision
+
+ def sin(x):
+ with localcontext(ExtendedContext):
+ # Rest of sin calculation algorithm
+ # uses the Extended Context from the
+ # General Decimal Arithmetic Specification
+ return +s # Convert result to normal context
+
+ """
+ # The string below can't be included in the docstring until Python 2.6
+ # as the doctest module doesn't understand __future__ statements
+ """
+ >>> from __future__ import with_statement
+ >>> print getcontext().prec
+ 28
+ >>> with localcontext():
+ ... ctx = getcontext()
+ ... ctx.prec() += 2
+ ... print ctx.prec
+ ...
+ 30
+ >>> with localcontext(ExtendedContext):
+ ... print getcontext().prec
+ ...
+ 9
+ >>> print getcontext().prec
+ 28
+ """
+ if ctx is None: ctx = getcontext()
+ return _ContextManager(ctx)
+
##### Decimal class ###########################################
@@ -2192,23 +2235,14 @@ for name in rounding_functions:
del name, val, globalname, rounding_functions
-class ContextManager(object):
- """Helper class to simplify Context management.
-
- Sample usage:
-
- with decimal.ExtendedContext:
- s = ...
- return +s # Convert result to normal precision
-
- with decimal.getcontext() as ctx:
- ctx.prec += 2
- s = ...
- return +s
+class _ContextManager(object):
+ """Context manager class to support localcontext().
+ Sets a copy of the supplied context in __enter__() and restores
+ the previous decimal context in __exit__()
"""
def __init__(self, new_context):
- self.new_context = new_context
+ self.new_context = new_context.copy()
def __enter__(self):
self.saved_context = getcontext()
setcontext(self.new_context)
@@ -2267,9 +2301,6 @@ class Context(object):
s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
return ', '.join(s) + ')'
- def get_manager(self):
- return ContextManager(self.copy())
-
def clear_flags(self):
"""Reset all flags to zero"""
for flag in self.flags:
diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py
index 5b09965..6f0e0d8 100644
--- a/Lib/distutils/command/bdist_rpm.py
+++ b/Lib/distutils/command/bdist_rpm.py
@@ -337,37 +337,47 @@ class bdist_rpm (Command):
if not self.keep_temp:
rpm_cmd.append('--clean')
rpm_cmd.append(spec_path)
+ # Determine the binary rpm names that should be built out of this spec
+ # file
+ # Note that some of these may not be really built (if the file
+ # list is empty)
+ nvr_string = "%{name}-%{version}-%{release}"
+ src_rpm = nvr_string + ".src.rpm"
+ non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm"
+ q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % (
+ src_rpm, non_src_rpm, spec_path)
+
+ out = os.popen(q_cmd)
+ binary_rpms = []
+ source_rpm = None
+ while 1:
+ line = out.readline()
+ if not line:
+ break
+ l = string.split(string.strip(line))
+ assert(len(l) == 2)
+ binary_rpms.append(l[1])
+ # The source rpm is named after the first entry in the spec file
+ if source_rpm is None:
+ source_rpm = l[0]
+
+ status = out.close()
+ if status:
+ raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd))
+
self.spawn(rpm_cmd)
- # XXX this is a nasty hack -- we really should have a proper way to
- # find out the names of the RPM files created; also, this assumes
- # that RPM creates exactly one source and one binary RPM.
if not self.dry_run:
if not self.binary_only:
- srpms = glob.glob(os.path.join(rpm_dir['SRPMS'], "*.rpm"))
- assert len(srpms) == 1, \
- "unexpected number of SRPM files found: %s" % srpms
- dist_file = ('bdist_rpm', 'any',
- self._dist_path(srpms[0]))
- self.distribution.dist_files.append(dist_file)
- self.move_file(srpms[0], self.dist_dir)
+ srpm = os.path.join(rpm_dir['SRPMS'], source_rpm)
+ assert(os.path.exists(srpm))
+ self.move_file(srpm, self.dist_dir)
if not self.source_only:
- rpms = glob.glob(os.path.join(rpm_dir['RPMS'], "*/*.rpm"))
- debuginfo = glob.glob(os.path.join(rpm_dir['RPMS'],
- "*/*debuginfo*.rpm"))
- if debuginfo:
- rpms.remove(debuginfo[0])
- assert len(rpms) == 1, \
- "unexpected number of RPM files found: %s" % rpms
- dist_file = ('bdist_rpm', get_python_version(),
- self._dist_path(rpms[0]))
- self.distribution.dist_files.append(dist_file)
- self.move_file(rpms[0], self.dist_dir)
- if debuginfo:
- dist_file = ('bdist_rpm', get_python_version(),
- self._dist_path(debuginfo[0]))
- self.move_file(debuginfo[0], self.dist_dir)
+ for rpm in binary_rpms:
+ rpm = os.path.join(rpm_dir['RPMS'], rpm)
+ if os.path.exists(rpm):
+ self.move_file(rpm, self.dist_dir)
# run()
def _dist_path(self, path):
@@ -381,6 +391,7 @@ class bdist_rpm (Command):
spec_file = [
'%define name ' + self.distribution.get_name(),
'%define version ' + self.distribution.get_version().replace('-','_'),
+ '%define unmangled_version ' + self.distribution.get_version(),
'%define release ' + self.release.replace('-','_'),
'',
'Summary: ' + self.distribution.get_description(),
@@ -402,9 +413,9 @@ class bdist_rpm (Command):
# but only after it has run: and we create the spec file before
# running "sdist", in case of --spec-only.
if self.use_bzip2:
- spec_file.append('Source0: %{name}-%{version}.tar.bz2')
+ spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2')
else:
- spec_file.append('Source0: %{name}-%{version}.tar.gz')
+ spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz')
spec_file.extend([
'License: ' + self.distribution.get_license(),
@@ -479,7 +490,7 @@ class bdist_rpm (Command):
# are just text that we drop in as-is. Hmmm.
script_options = [
- ('prep', 'prep_script', "%setup"),
+ ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"),
('build', 'build_script', def_build),
('install', 'install_script',
("%s install "
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index cd67544..f79eee3 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -186,7 +186,7 @@ class build_ext (Command):
# for extensions under Cygwin and AtheOS Python's library directory must be
# appended to library_dirs
if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos' or \
- (sys.platform.startswith('linux') and
+ ((sys.platform.startswith('linux') or sys.platform.startswith('gnu')) and
sysconfig.get_config_var('Py_ENABLE_SHARED')):
if string.find(sys.executable, sys.exec_prefix) != -1:
# building third party extensions
diff --git a/Lib/distutils/command/install_egg_info.py b/Lib/distutils/command/install_egg_info.py
index c31ac29..c888031 100644
--- a/Lib/distutils/command/install_egg_info.py
+++ b/Lib/distutils/command/install_egg_info.py
@@ -35,6 +35,9 @@ class install_egg_info(Command):
dir_util.remove_tree(target, dry_run=self.dry_run)
elif os.path.exists(target):
self.execute(os.unlink,(self.target,),"Removing "+target)
+ elif not os.path.isdir(self.install_dir):
+ self.execute(os.makedirs, (self.install_dir,),
+ "Creating "+self.install_dir)
log.info("Writing %s", target)
if not self.dry_run:
f = open(target, 'w')
diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py
index f891262..3177476 100644
--- a/Lib/distutils/command/register.py
+++ b/Lib/distutils/command/register.py
@@ -256,7 +256,7 @@ Your selection [default 1]: ''',
body = StringIO.StringIO()
for key, value in data.items():
# handle multiple entries for the same name
- if type(value) != type([]):
+ if type(value) not in (type([]), type( () )):
value = [value]
for value in value:
value = unicode(value).encode("utf-8")
diff --git a/Lib/distutils/command/wininst-8.exe b/Lib/distutils/command/wininst-8.exe
new file mode 100644
index 0000000..7403bfa
--- /dev/null
+++ b/Lib/distutils/command/wininst-8.exe
Binary files differ
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
index 96923bd..8989d92 100644
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -509,7 +509,10 @@ def get_config_vars(*args):
# are in CFLAGS or LDFLAGS and remove them if they are.
# This is needed when building extensions on a 10.3 system
# using a universal build of python.
- for key in ('LDFLAGS', 'BASECFLAGS'):
+ for key in ('LDFLAGS', 'BASECFLAGS',
+ # a number of derived variables. These need to be
+ # patched up as well.
+ 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
flags = _config_vars[key]
flags = re.sub('-arch\s+\w+\s', ' ', flags)
flags = re.sub('-isysroot [^ \t]*', ' ', flags)
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
index 6cd14f7..75e8a53 100644
--- a/Lib/distutils/unixccompiler.py
+++ b/Lib/distutils/unixccompiler.py
@@ -82,6 +82,22 @@ def _darwin_compiler_fixup(compiler_so, cc_args):
except ValueError:
pass
+ # Check if the SDK that is used during compilation actually exists,
+ # the universal build requires the usage of a universal SDK and not all
+ # users have that installed by default.
+ sysroot = None
+ if '-isysroot' in cc_args:
+ idx = cc_args.index('-isysroot')
+ sysroot = cc_args[idx+1]
+ elif '-isysroot' in compiler_so:
+ idx = compiler_so.index('-isysroot')
+ sysroot = compiler_so[idx+1]
+
+ if sysroot and not os.path.isdir(sysroot):
+ log.warn("Compiling with an SDK that doesn't seem to exist: %s",
+ sysroot)
+ log.warn("Please check your Xcode installation")
+
return compiler_so
class UnixCCompiler(CCompiler):
diff --git a/Lib/email/utils.py b/Lib/email/utils.py
index 26ebb0e..ee952d3 100644
--- a/Lib/email/utils.py
+++ b/Lib/email/utils.py
@@ -235,10 +235,6 @@ def decode_rfc2231(s):
parts = s.split(TICK, 2)
if len(parts) <= 2:
return None, None, s
- if len(parts) > 3:
- charset, language = parts[:2]
- s = TICK.join(parts[2:])
- return charset, language, s
return parts
diff --git a/Lib/encodings/__init__.py b/Lib/encodings/__init__.py
index b0ca364..f1e7ecc 100644
--- a/Lib/encodings/__init__.py
+++ b/Lib/encodings/__init__.py
@@ -28,7 +28,7 @@ Written by Marc-Andre Lemburg (mal@lemburg.com).
"""#"
-import codecs, types
+import codecs
from . import aliases
_cache = {}
@@ -60,7 +60,7 @@ def normalize_encoding(encoding):
"""
# Make sure we have an 8-bit string, because .translate() works
# differently for Unicode strings.
- if type(encoding) is types.UnicodeType:
+ if isinstance(encoding, unicode):
# Note that .encode('latin-1') does *not* use the codec
# registry, so this call doesn't recurse. (See unicodeobject.c
# PyUnicode_AsEncodedString() for details)
@@ -90,7 +90,7 @@ def search_function(encoding):
else:
modnames = [norm_encoding]
for modname in modnames:
- if not modname:
+ if not modname or '.' in modname:
continue
try:
mod = __import__('encodings.' + modname,
diff --git a/Lib/encodings/bz2_codec.py b/Lib/encodings/bz2_codec.py
index 81e84b6..054b36b 100644
--- a/Lib/encodings/bz2_codec.py
+++ b/Lib/encodings/bz2_codec.py
@@ -52,14 +52,35 @@ class Codec(codecs.Codec):
return bz2_decode(input, errors)
class IncrementalEncoder(codecs.IncrementalEncoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.compressobj = bz2.BZ2Compressor()
+
def encode(self, input, final=False):
- assert self.errors == 'strict'
- return bz2.compress(input)
+ if final:
+ c = self.compressobj.compress(input)
+ return c + self.compressobj.flush()
+ else:
+ return self.compressobj.compress(input)
+
+ def reset(self):
+ self.compressobj = bz2.BZ2Compressor()
class IncrementalDecoder(codecs.IncrementalDecoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.decompressobj = bz2.BZ2Decompressor()
+
def decode(self, input, final=False):
- assert self.errors == 'strict'
- return bz2.decompress(input)
+ try:
+ return self.decompressobj.decompress(input)
+ except EOFError:
+ return ''
+
+ def reset(self):
+ self.decompressobj = bz2.BZ2Decompressor()
class StreamWriter(Codec,codecs.StreamWriter):
pass
diff --git a/Lib/encodings/utf_8_sig.py b/Lib/encodings/utf_8_sig.py
index f05f6b8..d751da6 100644
--- a/Lib/encodings/utf_8_sig.py
+++ b/Lib/encodings/utf_8_sig.py
@@ -16,7 +16,7 @@ def encode(input, errors='strict'):
def decode(input, errors='strict'):
prefix = 0
- if input.startswith(codecs.BOM_UTF8):
+ if input[:3] == codecs.BOM_UTF8:
input = input[3:]
prefix = 3
(output, consumed) = codecs.utf_8_decode(input, errors, True)
diff --git a/Lib/encodings/zlib_codec.py b/Lib/encodings/zlib_codec.py
index 2694f15..3419f9f 100644
--- a/Lib/encodings/zlib_codec.py
+++ b/Lib/encodings/zlib_codec.py
@@ -51,14 +51,36 @@ class Codec(codecs.Codec):
return zlib_decode(input, errors)
class IncrementalEncoder(codecs.IncrementalEncoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.compressobj = zlib.compressobj()
+
def encode(self, input, final=False):
- assert self.errors == 'strict'
- return zlib.compress(input)
+ if final:
+ c = self.compressobj.compress(input)
+ return c + self.compressobj.flush()
+ else:
+ return self.compressobj.compress(input)
+
+ def reset(self):
+ self.compressobj = zlib.compressobj()
class IncrementalDecoder(codecs.IncrementalDecoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.decompressobj = zlib.decompressobj()
+
def decode(self, input, final=False):
- assert self.errors == 'strict'
- return zlib.decompress(input)
+ if final:
+ c = self.decompressobj.decompress(input)
+ return c + self.decompressobj.flush()
+ else:
+ return self.decompressobj.decompress(input)
+
+ def reset(self):
+ self.decompressobj = zlib.decompressobj()
class StreamWriter(Codec,codecs.StreamWriter):
pass
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index 937ee4e..9cb67dd 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -325,6 +325,14 @@ class FTP:
if rest is not None:
self.sendcmd("REST %s" % rest)
resp = self.sendcmd(cmd)
+ # Some servers apparently send a 200 reply to
+ # a LIST or STOR command, before the 150 reply
+ # (and way before the 226 reply). This seems to
+ # be in violation of the protocol (which only allows
+ # 1xx or error messages for LIST), so we just discard
+ # this response.
+ if resp[0] == '2':
+ resp = self.getresp()
if resp[0] != '1':
raise error_reply, resp
else:
@@ -332,6 +340,9 @@ class FTP:
if rest is not None:
self.sendcmd("REST %s" % rest)
resp = self.sendcmd(cmd)
+ # See above.
+ if resp[0] == '2':
+ resp = self.getresp()
if resp[0] != '1':
raise error_reply, resp
conn, sockaddr = sock.accept()
diff --git a/Lib/functools.py b/Lib/functools.py
index 12a527e..a54f030 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -25,14 +25,14 @@ def update_wrapper(wrapper,
assigned is a tuple naming the attributes assigned directly
from the wrapped function to the wrapper function (defaults to
functools.WRAPPER_ASSIGNMENTS)
- updated is a tuple naming the attributes off the wrapper that
+ updated is a tuple naming the attributes of the wrapper that
are updated with the corresponding attribute from the wrapped
function (defaults to functools.WRAPPER_UPDATES)
"""
for attr in assigned:
setattr(wrapper, attr, getattr(wrapped, attr))
for attr in updated:
- getattr(wrapper, attr).update(getattr(wrapped, attr))
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
# Return the wrapper so this can be used as a decorator via partial()
return wrapper
diff --git a/Lib/genericpath.py b/Lib/genericpath.py
new file mode 100644
index 0000000..1574cef
--- /dev/null
+++ b/Lib/genericpath.py
@@ -0,0 +1,77 @@
+"""
+Path operations common to more than one OS
+Do not use directly. The OS specific modules import the appropriate
+functions from this module themselves.
+"""
+import os
+import stat
+
+__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
+ 'getsize', 'isdir', 'isfile']
+
+
+# Does a path exist?
+# This is false for dangling symbolic links on systems that support them.
+def exists(path):
+ """Test whether a path exists. Returns False for broken symbolic links"""
+ try:
+ st = os.stat(path)
+ except os.error:
+ return False
+ return True
+
+
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path ono systems that support symlinks
+def isfile(path):
+ """Test whether a path is a regular file"""
+ try:
+ st = os.stat(path)
+ except os.error:
+ return False
+ return stat.S_ISREG(st.st_mode)
+
+
+# Is a path a directory?
+# This follows symbolic links, so both islink() and isdir()
+# can be true for the same path on systems that support symlinks
+def isdir(s):
+ """Return true if the pathname refers to an existing directory."""
+ try:
+ st = os.stat(s)
+ except os.error:
+ return False
+ return stat.S_ISDIR(st.st_mode)
+
+
+def getsize(filename):
+ """Return the size of a file, reported by os.stat()."""
+ return os.stat(filename).st_size
+
+
+def getmtime(filename):
+ """Return the last modification time of a file, reported by os.stat()."""
+ return os.stat(filename).st_mtime
+
+
+def getatime(filename):
+ """Return the last access time of a file, reported by os.stat()."""
+ return os.stat(filename).st_atime
+
+
+def getctime(filename):
+ """Return the metadata change time of a file, reported by os.stat()."""
+ return os.stat(filename).st_ctime
+
+
+# Return the longest prefix of all list elements.
+def commonprefix(m):
+ "Given a list of pathnames, returns the longest common leading component"
+ if not m: return ''
+ s1 = min(m)
+ s2 = max(m)
+ n = min(len(s1), len(s2))
+ for i in xrange(n):
+ if s1[i] != s2[i]:
+ return s1[:i]
+ return s1[:n]
diff --git a/Lib/gzip.py b/Lib/gzip.py
index 0bf29e8..c37d5a1 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -371,7 +371,12 @@ class GzipFile:
self.extrasize = 0
self.offset = 0
- def seek(self, offset):
+ def seek(self, offset, whence=0):
+ if whence:
+ if whence == 1:
+ offset = self.offset + offset
+ else:
+ raise ValueError('Seek from end not supported')
if self.mode == WRITE:
if offset < self.offset:
raise IOError('Negative seek in write mode')
diff --git a/Lib/hashlib.py b/Lib/hashlib.py
index 789e24e..78b5c0e 100644
--- a/Lib/hashlib.py
+++ b/Lib/hashlib.py
@@ -18,8 +18,37 @@ md5(), sha1(), sha224(), sha256(), sha384(), and sha512()
More algorithms may be available on your platform but the above are
guaranteed to exist.
-Choose your hash function wisely. Some have known weaknesses.
+Choose your hash function wisely. Some have known collision weaknesses.
sha384 and sha512 will be slow on 32 bit platforms.
+
+Hash objects have these methods:
+ - update(arg): Update the hash object with the string arg. Repeated calls
+ are equivalent to a single call with the concatenation of all
+ the arguments.
+ - digest(): Return the digest of the strings passed to the update() method
+ so far. This may contain non-ASCII characters, including
+ NUL bytes.
+ - hexdigest(): Like digest() except the digest is returned as a string of
+ double length, containing only hexadecimal digits.
+ - copy(): Return a copy (clone) of the hash object. This can be used to
+ efficiently compute the digests of strings that share a common
+ initial substring.
+
+For example, to obtain the digest of the string 'Nobody inspects the
+spammish repetition':
+
+ >>> import hashlib
+ >>> m = hashlib.md5()
+ >>> m.update("Nobody inspects")
+ >>> m.update(" the spammish repetition")
+ >>> m.digest()
+ '\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+
+More condensed:
+
+ >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
+ 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
+
"""
diff --git a/Lib/httplib.py b/Lib/httplib.py
index 5ae5efc..1e0037f 100644
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -704,7 +704,15 @@ class HTTPConnection:
if self.debuglevel > 0:
print "send:", repr(str)
try:
- self.sock.sendall(str)
+ blocksize=8192
+ if hasattr(str,'read') :
+ if self.debuglevel > 0: print "sendIng a read()able"
+ data=str.read(blocksize)
+ while data:
+ self.sock.sendall(data)
+ data=str.read(blocksize)
+ else:
+ self.sock.sendall(str)
except socket.error, v:
if v[0] == 32: # Broken pipe
self.close()
@@ -879,7 +887,21 @@ class HTTPConnection:
self.putrequest(method, url, **skips)
if body and ('content-length' not in header_names):
- self.putheader('Content-Length', str(len(body)))
+ thelen=None
+ try:
+ thelen=str(len(body))
+ except TypeError, te:
+ # If this is a file-like object, try to
+ # fstat its file descriptor
+ import os
+ try:
+ thelen = str(os.fstat(body.fileno()).st_size)
+ except (AttributeError, OSError):
+ # Don't send a length if this failed
+ if self.debuglevel > 0: print "Cannot stat!!"
+
+ if thelen is not None:
+ self.putheader('Content-Length',thelen)
for hdr, value in headers.iteritems():
self.putheader(hdr, value)
self.endheaders()
diff --git a/Lib/idlelib/CodeContext.py b/Lib/idlelib/CodeContext.py
index 74d5b70..436206f 100644
--- a/Lib/idlelib/CodeContext.py
+++ b/Lib/idlelib/CodeContext.py
@@ -54,25 +54,68 @@ class CodeContext:
def toggle_code_context_event(self, event=None):
if not self.label:
- self.pad_frame = Tkinter.Frame(self.editwin.top,
- bg=self.bgcolor, border=2,
- relief="sunken")
- self.label = Tkinter.Label(self.pad_frame,
- text="\n" * (self.context_depth - 1),
- anchor="w", justify="left",
- font=self.textfont,
- bg=self.bgcolor, fg=self.fgcolor,
- border=0,
- width=1, # Don't request more than we get
- )
- self.label.pack(side="top", fill="x", expand=True,
- padx=4, pady=0)
- self.pad_frame.pack(side="top", fill="x", expand=False,
- padx=0, pady=0,
- after=self.editwin.status_bar)
+ # The following code attempts to figure out the required border
+ # width and vertical padding required for the CodeContext widget
+ # to be perfectly aligned with the text in the main Text widget.
+ # This is done by retrieving the appropriate attributes from the
+ # editwin.text and editwin.text_frame widgets.
+ #
+ # All values are passed through int(str(<value>)), since some
+ # values may be pixel objects, which can't simply be added added
+ # to ints.
+ #
+ # This code is considered somewhat unstable since it relies on
+ # some of Tk's inner workings. However its effect is merely
+ # cosmetic; failure will only cause the CodeContext text to be
+ # somewhat misaligned with the text in the main Text widget.
+ #
+ # To avoid possible errors, all references to the inner workings
+ # of Tk are executed inside try/except blocks.
+
+ widgets_for_width_calc = self.editwin.text, self.editwin.text_frame
+
+ # calculate the required vertical padding
+ padx = 0
+ for widget in widgets_for_width_calc:
+ try:
+ # retrieve the "padx" attribte from widget's pack info
+ padx += int(str( widget.pack_info()['padx'] ))
+ except:
+ pass
+ try:
+ # retrieve the widget's "padx" attribte
+ padx += int(str( widget.cget('padx') ))
+ except:
+ pass
+
+ # calculate the required border width
+ border_width = 0
+ for widget in widgets_for_width_calc:
+ try:
+ # retrieve the widget's "border" attribte
+ border_width += int(str( widget.cget('border') ))
+ except:
+ pass
+
+ self.label = Tkinter.Label(self.editwin.top,
+ text="\n" * (self.context_depth - 1),
+ anchor="w", justify="left",
+ font=self.textfont,
+ bg=self.bgcolor, fg=self.fgcolor,
+ width=1, #don't request more than we get
+ padx=padx, #line up with text widget
+ border=border_width, #match border width
+ relief="sunken",
+ )
+
+ # CodeContext's label widget is packed before and above the
+ # text_frame widget, thus ensuring that it will appear directly
+ # above it.
+ self.label.pack(side="top", fill="x", expand=False,
+ before=self.editwin.text_frame)
+
else:
self.label.destroy()
- self.pad_frame.destroy()
self.label = None
idleConf.SetOption("extensions", "CodeContext", "visible",
str(self.label is not None))
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index bc61afb..1841b1c 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -102,8 +102,8 @@ class EditorWindow(object):
self.top.instance_dict = {}
self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(),
'recent-files.lst')
- self.vbar = vbar = Scrollbar(top, name='vbar')
self.text_frame = text_frame = Frame(top)
+ self.vbar = vbar = Scrollbar(text_frame, name='vbar')
self.width = idleConf.GetOption('main','EditorWindow','width')
self.text = text = MultiCallCreator(Text)(
text_frame, name='text', padx=5, wrap='none',
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 3b3d79a..43e5b45 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -3,6 +3,13 @@ What's New in IDLE 2.6a1?
*Release date: XX-XXX-200X*
+- Patch #1362975: Rework CodeContext indentation algorithm to
+ avoid hard-coding pixel widths.
+
+- Some syntax errors were being caught by tokenize during the tabnanny
+ check, resulting in obscure error messages. Do the syntax check
+ first. Bug 1562716, 1562719
+
- IDLE's version number takes a big jump to match the version number of
the Python release of which it's a part.
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index 709b3a7..20d00be 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -351,6 +351,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
def build_subprocess_arglist(self):
w = ['-W' + s for s in sys.warnoptions]
+ if 1/2 > 0: # account for new division
+ w.append('-Qnew')
# Maybe IDLE is installed and is being accessed via sys.path,
# or maybe it's not installed and the idle.py script is being
# run from the IDLE source directory.
@@ -726,6 +728,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
raise
except:
if use_subprocess:
+ # When run w/o subprocess, both user and IDLE errors
+ # are printed here; skip message in that case.
print >> self.tkconsole.stderr, \
"IDLE internal error in runcode()"
self.showtraceback()
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
index f325ad1..3746eb8 100644
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -57,9 +57,10 @@ class ScriptBinding:
filename = self.getfilename()
if not filename:
return
+ if not self.checksyntax(filename):
+ return
if not self.tabnanny(filename):
return
- self.checksyntax(filename)
def tabnanny(self, filename):
f = open(filename, 'r')
@@ -76,9 +77,6 @@ class ScriptBinding:
self.editwin.gotoline(nag.get_lineno())
self.errorbox("Tab/space error", indent_message)
return False
- except IndentationError:
- # From tokenize(), let compile() in checksyntax find it again.
- pass
return True
def checksyntax(self, filename):
@@ -139,11 +137,11 @@ class ScriptBinding:
filename = self.getfilename()
if not filename:
return
- if not self.tabnanny(filename):
- return
code = self.checksyntax(filename)
if not code:
return
+ if not self.tabnanny(filename):
+ return
shell = self.shell
interp = shell.interp
if PyShell.use_subprocess:
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 0b498b5..986a415 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -403,6 +403,7 @@ def getabsfile(object, _filename=None):
return os.path.normcase(os.path.abspath(_filename))
modulesbyfile = {}
+_filesbymodname = {}
def getmodule(object, _filename=None):
"""Return the module an object was defined in, or None if not found."""
@@ -410,19 +411,32 @@ def getmodule(object, _filename=None):
return object
if hasattr(object, '__module__'):
return sys.modules.get(object.__module__)
+ # Try the filename to modulename cache
+ if _filename is not None and _filename in modulesbyfile:
+ return sys.modules.get(modulesbyfile[_filename])
+ # Try the cache again with the absolute file name
try:
file = getabsfile(object, _filename)
except TypeError:
return None
if file in modulesbyfile:
return sys.modules.get(modulesbyfile[file])
- for module in sys.modules.values():
+ # Update the filename to module name cache and check yet again
+ # Copy sys.modules in order to cope with changes while iterating
+ for modname, module in sys.modules.items():
if ismodule(module) and hasattr(module, '__file__'):
+ f = module.__file__
+ if f == _filesbymodname.get(modname, None):
+ # Have already mapped this module, so skip it
+ continue
+ _filesbymodname[modname] = f
f = getabsfile(module)
+ # Always map to the name the module knows itself by
modulesbyfile[f] = modulesbyfile[
os.path.realpath(f)] = module.__name__
if file in modulesbyfile:
return sys.modules.get(modulesbyfile[file])
+ # Check the main module
main = sys.modules['__main__']
if not hasattr(object, '__name__'):
return None
@@ -430,6 +444,7 @@ def getmodule(object, _filename=None):
mainobject = getattr(main, object.__name__)
if mainobject is object:
return main
+ # Check builtins
builtin = sys.modules['__builtin__']
if hasattr(builtin, object.__name__):
builtinobject = getattr(builtin, object.__name__)
@@ -444,7 +459,7 @@ def findsource(object):
in the file and the line number indexes a line in that list. An IOError
is raised if the source code cannot be retrieved."""
file = getsourcefile(object) or getfile(object)
- module = getmodule(object)
+ module = getmodule(object, file)
if module:
lines = linecache.getlines(file, module.__dict__)
else:
@@ -457,9 +472,24 @@ def findsource(object):
if isclass(object):
name = object.__name__
- pat = re.compile(r'^\s*class\s*' + name + r'\b')
+ pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
+ # make some effort to find the best matching class definition:
+ # use the one with the least indentation, which is the one
+ # that's most probably not inside a function definition.
+ candidates = []
for i in range(len(lines)):
- if pat.match(lines[i]): return lines, i
+ match = pat.match(lines[i])
+ if match:
+ # if it's at toplevel, it's already the best one
+ if lines[i][0] == 'c':
+ return lines, i
+ # else add whitespace to candidate list
+ candidates.append((match.group(1), i))
+ if candidates:
+ # this will sort by whitespace, and by line number,
+ # less whitespace first
+ candidates.sort()
+ return lines, candidates[0][1]
else:
raise IOError('could not find class definition')
diff --git a/Lib/lib-tk/Tix.py b/Lib/lib-tk/Tix.py
index 1d2fdad..ad6126a 100755
--- a/Lib/lib-tk/Tix.py
+++ b/Lib/lib-tk/Tix.py
@@ -421,7 +421,7 @@ class TixSubWidget(TixWidget):
except:
plist = []
- if (not check_intermediate) or len(plist) < 2:
+ if not check_intermediate:
# immediate descendant
TixWidget.__init__(self, master, None, None, {'name' : name})
else:
@@ -437,6 +437,9 @@ class TixSubWidget(TixWidget):
parent = TixSubWidget(parent, plist[i],
destroy_physically=0,
check_intermediate=0)
+ # The Tk widget name is in plist, not in name
+ if plist:
+ name = plist[-1]
TixWidget.__init__(self, parent, None, None, {'name' : name})
self.destroy_physically = destroy_physically
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index bea130c..f8538ed 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -3017,7 +3017,7 @@ class Text(Widget):
self.tk.call(self._w, 'scan', 'dragto', x, y)
def search(self, pattern, index, stopindex=None,
forwards=None, backwards=None, exact=None,
- regexp=None, nocase=None, count=None):
+ regexp=None, nocase=None, count=None, elide=None):
"""Search PATTERN beginning from INDEX until STOPINDEX.
Return the index of the first character of a match or an empty string."""
args = [self._w, 'search']
@@ -3026,6 +3026,7 @@ class Text(Widget):
if exact: args.append('-exact')
if regexp: args.append('-regexp')
if nocase: args.append('-nocase')
+ if elide: args.append('-elide')
if count: args.append('-count'); args.append(count)
if pattern[0] == '-': args.append('--')
args.append(pattern)
diff --git a/Lib/lib-tk/tkMessageBox.py b/Lib/lib-tk/tkMessageBox.py
index aff069b..d14ca86 100644
--- a/Lib/lib-tk/tkMessageBox.py
+++ b/Lib/lib-tk/tkMessageBox.py
@@ -102,6 +102,15 @@ def askyesno(title=None, message=None, **options):
s = _show(title, message, QUESTION, YESNO, **options)
return s == YES
+def askyesnocancel(title=None, message=None, **options):
+ "Ask a question; return true if the answer is yes, None if cancelled."
+ s = _show(title, message, QUESTION, YESNOCANCEL, **options)
+ # s might be a Tcl index object, so convert it to a string
+ s = str(s)
+ if s == CANCEL:
+ return None
+ return s == YES
+
def askretrycancel(title=None, message=None, **options):
"Ask if operation should be retried; return true if the answer is yes"
s = _show(title, message, WARNING, RETRYCANCEL, **options)
@@ -119,4 +128,5 @@ if __name__ == "__main__":
print "question", askquestion("Spam", "Question?")
print "proceed", askokcancel("Spam", "Proceed?")
print "yes/no", askyesno("Spam", "Got it?")
+ print "yes/no/cancel", askyesnocancel("Spam", "Want it?")
print "try again", askretrycancel("Spam", "Try again?")
diff --git a/Lib/lib-tk/tkSimpleDialog.py b/Lib/lib-tk/tkSimpleDialog.py
index 7b70411..3411d94 100644
--- a/Lib/lib-tk/tkSimpleDialog.py
+++ b/Lib/lib-tk/tkSimpleDialog.py
@@ -46,8 +46,13 @@ class Dialog(Toplevel):
title -- the dialog title
'''
Toplevel.__init__(self, parent)
- self.transient(parent)
+ # If the master is not viewable, don't
+ # make the child transient, or else it
+ # would be opened withdrawn
+ if parent.winfo_viewable():
+ self.transient(parent)
+
if title:
self.title(title)
@@ -124,9 +129,10 @@ class Dialog(Toplevel):
self.withdraw()
self.update_idletasks()
- self.apply()
-
- self.cancel()
+ try:
+ self.apply()
+ finally:
+ self.cancel()
def cancel(self, event=None):
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index 01a55b1..fcde9af 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -15,6 +15,7 @@ pictures can easily be drawn.
"""
from math import * # Also for export
+from time import sleep
import Tkinter
speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
@@ -949,7 +950,6 @@ def demo2():
if __name__ == '__main__':
- from time import sleep
demo()
sleep(3)
demo2()
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 953afe9..b57a9af 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -214,7 +214,7 @@ class LogRecord:
information to be logged.
"""
def __init__(self, name, level, pathname, lineno,
- msg, args, exc_info, func):
+ msg, args, exc_info, func=None):
"""
Initialize a logging record with interesting information.
"""
@@ -910,10 +910,11 @@ class Manager:
Ensure that children of the placeholder ph are connected to the
specified logger.
"""
- #for c in ph.loggers:
+ name = alogger.name
+ namelen = len(name)
for c in ph.loggerMap.keys():
- # XXX Is the following correct? Shouldn't it be >= 0?
- if string.find(c.parent.name, alogger.name) != 0:
+ #The if means ... if not c.parent.name.startswith(nm)
+ if c.parent.name[:namelen] != name:
alogger.parent = c.parent
c.parent = alogger
diff --git a/Lib/logging/config.py b/Lib/logging/config.py
index a31e8d0..a9970d0 100644
--- a/Lib/logging/config.py
+++ b/Lib/logging/config.py
@@ -27,7 +27,7 @@ Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging' and log away!
"""
-import sys, logging, logging.handlers, string, socket, struct, os, traceback
+import sys, logging, logging.handlers, string, socket, struct, os, traceback, types
try:
import thread
@@ -110,7 +110,7 @@ def _create_formatters(cp):
flist = string.split(flist, ",")
formatters = {}
for form in flist:
- sectname = "formatter_%s" % form
+ sectname = "formatter_%s" % string.strip(form)
opts = cp.options(sectname)
if "format" in opts:
fs = cp.get(sectname, "format", 1)
@@ -139,7 +139,7 @@ def _install_handlers(cp, formatters):
handlers = {}
fixups = [] #for inter-handler references
for hand in hlist:
- sectname = "handler_%s" % hand
+ sectname = "handler_%s" % string.strip(hand)
klass = cp.get(sectname, "class")
opts = cp.options(sectname)
if "formatter" in opts:
@@ -176,6 +176,7 @@ def _install_loggers(cp, handlers):
# configure the root first
llist = cp.get("loggers", "keys")
llist = string.split(llist, ",")
+ llist = map(lambda x: string.strip(x), llist)
llist.remove("root")
sectname = "logger_root"
root = logging.root
@@ -190,7 +191,7 @@ def _install_loggers(cp, handlers):
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
- log.addHandler(handlers[hand])
+ log.addHandler(handlers[string.strip(hand)])
#and now the others...
#we don't want to lose the existing loggers,
@@ -225,7 +226,7 @@ def _install_loggers(cp, handlers):
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
- logger.addHandler(handlers[hand])
+ logger.addHandler(handlers[string.strip(hand)])
#Disable any old loggers. There's no point deleting
#them as other threads may continue to hold references
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index a0255ce..17eca8a 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -590,11 +590,11 @@ class SysLogHandler(logging.Handler):
self.address = address
self.facility = facility
if type(address) == types.StringType:
- self._connect_unixsocket(address)
self.unixsocket = 1
+ self._connect_unixsocket(address)
else:
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.unixsocket = 0
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.formatter = None
diff --git a/Lib/macpath.py b/Lib/macpath.py
index f93ceb1..d389d70 100644
--- a/Lib/macpath.py
+++ b/Lib/macpath.py
@@ -2,6 +2,7 @@
import os
from stat import *
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -101,31 +102,6 @@ def ismount(s):
components = split(s)
return len(components) == 2 and components[1] == ''
-def isdir(s):
- """Return true if the pathname refers to an existing directory."""
-
- try:
- st = os.stat(s)
- except os.error:
- return 0
- return S_ISDIR(st.st_mode)
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
-
-
def islink(s):
"""Return true if the pathname refers to a symbolic link."""
@@ -135,29 +111,6 @@ def islink(s):
except:
return False
-
-def isfile(s):
- """Return true if the pathname refers to an existing regular file."""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return S_ISREG(st.st_mode)
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-def exists(s):
- """Test whether a path exists. Returns False for broken symbolic links"""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return True
-
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
# case.
@@ -170,20 +123,6 @@ def lexists(path):
return False
return True
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
def expandvars(path):
"""Dummy to retain interface-compatibility with other operating systems."""
return path
diff --git a/Lib/mailbox.py b/Lib/mailbox.py
index ed7c7d1..0843430 100755
--- a/Lib/mailbox.py
+++ b/Lib/mailbox.py
@@ -2,6 +2,12 @@
"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes."""
+# Notes for authors of new mailbox subclasses:
+#
+# Remember to fsync() changes to disk before closing a modified file
+# or returning from a flush() method. See functions _sync_flush() and
+# _sync_close().
+
import sys
import os
import time
@@ -235,7 +241,7 @@ class Maildir(Mailbox):
try:
self._dump_message(message, tmp_file)
finally:
- tmp_file.close()
+ _sync_close(tmp_file)
if isinstance(message, MaildirMessage):
subdir = message.get_subdir()
suffix = self.colon + message.get_info()
@@ -246,7 +252,19 @@ class Maildir(Mailbox):
suffix = ''
uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
dest = os.path.join(self._path, subdir, uniq + suffix)
- os.rename(tmp_file.name, dest)
+ try:
+ if hasattr(os, 'link'):
+ os.link(tmp_file.name, dest)
+ os.remove(tmp_file.name)
+ else:
+ os.rename(tmp_file.name, dest)
+ except OSError, e:
+ os.remove(tmp_file.name)
+ if e.errno == errno.EEXIST:
+ raise ExternalClashError('Name clash with existing message: %s'
+ % dest)
+ else:
+ raise
if isinstance(message, MaildirMessage):
os.utime(dest, (os.path.getatime(dest), message.get_date()))
return uniq
@@ -364,12 +382,14 @@ class Maildir(Mailbox):
def get_folder(self, folder):
"""Return a Maildir instance for the named folder."""
- return Maildir(os.path.join(self._path, '.' + folder), create=False)
+ return Maildir(os.path.join(self._path, '.' + folder),
+ factory=self._factory,
+ create=False)
def add_folder(self, folder):
"""Create a folder and return a Maildir instance representing it."""
path = os.path.join(self._path, '.' + folder)
- result = Maildir(path)
+ result = Maildir(path, factory=self._factory)
maildirfolder_path = os.path.join(path, 'maildirfolder')
if not os.path.exists(maildirfolder_path):
os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY))
@@ -420,12 +440,17 @@ class Maildir(Mailbox):
except OSError, e:
if e.errno == errno.ENOENT:
Maildir._count += 1
- return open(path, 'wb+')
+ try:
+ return _create_carefully(path)
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
else:
raise
- else:
- raise ExternalClashError('Name clash prevented file creation: %s' %
- path)
+
+ # Fall through to here if stat succeeded or open raised EEXIST.
+ raise ExternalClashError('Name clash prevented file creation: %s' %
+ path)
def _refresh(self):
"""Update table of contents mapping."""
@@ -560,7 +585,8 @@ class _singlefileMailbox(Mailbox):
new_file.close()
os.remove(new_file.name)
raise
- new_file.close()
+ _sync_close(new_file)
+ # self._file is about to get replaced, so no need to sync.
self._file.close()
try:
os.rename(new_file.name, self._path)
@@ -575,7 +601,7 @@ class _singlefileMailbox(Mailbox):
self._toc = new_toc
self._pending = False
if self._locked:
- _lock_file(new_file, dotlock=False)
+ _lock_file(self._file, dotlock=False)
def _pre_mailbox_hook(self, f):
"""Called before writing the mailbox to file f."""
@@ -594,7 +620,7 @@ class _singlefileMailbox(Mailbox):
self.flush()
if self._locked:
self.unlock()
- self._file.close()
+ self._file.close() # Sync has been done by self.flush() above.
def _lookup(self, key=None):
"""Return (start, stop) or raise KeyError."""
@@ -784,7 +810,7 @@ class MH(Mailbox):
if self._locked:
_unlock_file(f)
finally:
- f.close()
+ _sync_close(f)
return new_key
def remove(self, key):
@@ -831,7 +857,7 @@ class MH(Mailbox):
if self._locked:
_unlock_file(f)
finally:
- f.close()
+ _sync_close(f)
def get_message(self, key):
"""Return a Message representation or raise a KeyError."""
@@ -918,7 +944,7 @@ class MH(Mailbox):
"""Unlock the mailbox if it is locked."""
if self._locked:
_unlock_file(self._file)
- self._file.close()
+ _sync_close(self._file)
del self._file
self._locked = False
@@ -941,11 +967,13 @@ class MH(Mailbox):
def get_folder(self, folder):
"""Return an MH instance for the named folder."""
- return MH(os.path.join(self._path, folder), create=False)
+ return MH(os.path.join(self._path, folder),
+ factory=self._factory, create=False)
def add_folder(self, folder):
"""Create a folder and return an MH instance representing it."""
- return MH(os.path.join(self._path, folder))
+ return MH(os.path.join(self._path, folder),
+ factory=self._factory)
def remove_folder(self, folder):
"""Delete the named folder, which must be empty."""
@@ -1013,7 +1041,7 @@ class MH(Mailbox):
else:
f.write('\n')
finally:
- f.close()
+ _sync_close(f)
def pack(self):
"""Re-name messages to eliminate numbering gaps. Invalidates keys."""
@@ -1023,27 +1051,13 @@ class MH(Mailbox):
for key in self.iterkeys():
if key - 1 != prev:
changes.append((key, prev + 1))
- f = open(os.path.join(self._path, str(key)), 'r+')
- try:
- if self._locked:
- _lock_file(f)
- try:
- if hasattr(os, 'link'):
- os.link(os.path.join(self._path, str(key)),
- os.path.join(self._path, str(prev + 1)))
- if sys.platform == 'os2emx':
- # cannot unlink an open file on OS/2
- f.close()
- os.unlink(os.path.join(self._path, str(key)))
- else:
- f.close()
- os.rename(os.path.join(self._path, str(key)),
- os.path.join(self._path, str(prev + 1)))
- finally:
- if self._locked:
- _unlock_file(f)
- finally:
- f.close()
+ if hasattr(os, 'link'):
+ os.link(os.path.join(self._path, str(key)),
+ os.path.join(self._path, str(prev + 1)))
+ os.unlink(os.path.join(self._path, str(key)))
+ else:
+ os.rename(os.path.join(self._path, str(key)),
+ os.path.join(self._path, str(prev + 1)))
prev += 1
self._next_key = prev + 1
if len(changes) == 0:
@@ -1867,6 +1881,15 @@ def _create_temporary(path):
socket.gethostname(),
os.getpid()))
+def _sync_flush(f):
+ """Ensure changes to file f are physically on disk."""
+ f.flush()
+ os.fsync(f.fileno())
+
+def _sync_close(f):
+ """Close file f, ensuring all changes are physically on disk."""
+ _sync_flush(f)
+ f.close()
## Start: classes from the original module (for backward compatibility).
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 7a79b53..b32ec16 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -8,6 +8,7 @@ module as os.path.
import os
import stat
import sys
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -206,86 +207,18 @@ def dirname(p):
"""Returns the directory component of a pathname"""
return split(p)[0]
-
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
# Is a path a symbolic link?
# This will always return false on systems where posix.lstat doesn't exist.
def islink(path):
- """Test for symbolic link. On WindowsNT/95 always returns false"""
+ """Test for symbolic link.
+ On WindowsNT/95 and OS/2 always returns false
+ """
return False
-
-# Does a path exist?
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
-
-# Is a path a dos directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
diff --git a/Lib/os.py b/Lib/os.py
index 5ee3d4b..35f97fb 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -156,11 +156,17 @@ def makedirs(name, mode=0777):
recursive.
"""
+ from errno import EEXIST
head, tail = path.split(name)
if not tail:
head, tail = path.split(head)
if head and tail and not path.exists(head):
- makedirs(head, mode)
+ try:
+ makedirs(head, mode)
+ except OSError, e:
+ # be happy if someone already created the path
+ if e.errno != EEXIST:
+ raise
if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
return
mkdir(name, mode)
diff --git a/Lib/os2emxpath.py b/Lib/os2emxpath.py
index a841422..4e85c4d 100644
--- a/Lib/os2emxpath.py
+++ b/Lib/os2emxpath.py
@@ -7,6 +7,9 @@ module as os.path.
import os
import stat
+from genericpath import *
+from ntpath import (expanduser, expandvars, isabs, islink, splitdrive,
+ splitext, split, walk)
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -36,18 +39,6 @@ def normcase(s):
return s.replace('\\', '/').lower()
-# Return whether a path is absolute.
-# Trivial in Posix, harder on the Mac or MS-DOS.
-# For DOS it is absolute if it starts with a slash or backslash (current
-# volume), or if a pathname after the volume letter and colon / UNC resource
-# starts with a slash or backslash.
-
-def isabs(s):
- """Test whether a path is absolute"""
- s = splitdrive(s)[1]
- return s != '' and s[:1] in '/\\'
-
-
# Join two (or more) paths.
def join(a, *p):
@@ -63,17 +54,6 @@ def join(a, *p):
return path
-# Split a path in a drive specification (a drive letter followed by a
-# colon) and the path specification.
-# It is always true that drivespec + pathspec == p
-def splitdrive(p):
- """Split a pathname into drive and path specifiers. Returns a 2-tuple
-"(drive,path)"; either part may be empty"""
- if p[1:2] == ':':
- return p[0:2], p[2:]
- return '', p
-
-
# Parse UNC paths
def splitunc(p):
"""Split a pathname into UNC mount point and relative path specifiers.
@@ -103,57 +83,6 @@ def splitunc(p):
return '', p
-# Split a path in head (everything up to the last '/') and tail (the
-# rest). After the trailing '/' is stripped, the invariant
-# join(head, tail) == p holds.
-# The resulting head won't end in '/' unless it is the root.
-
-def split(p):
- """Split a pathname.
-
- Return tuple (head, tail) where tail is everything after the final slash.
- Either part may be empty."""
-
- d, p = splitdrive(p)
- # set i to index beyond p's last slash
- i = len(p)
- while i and p[i-1] not in '/\\':
- i = i - 1
- head, tail = p[:i], p[i:] # now tail has no slashes
- # remove trailing slashes from head, unless it's all slashes
- head2 = head
- while head2 and head2[-1] in '/\\':
- head2 = head2[:-1]
- head = head2 or head
- return d + head, tail
-
-
-# Split a path in root and extension.
-# The extension is everything starting at the last dot in the last
-# pathname component; the root is everything before that.
-# It is always true that root + ext == p.
-
-def splitext(p):
- """Split the extension from a pathname.
-
- Extension is everything from the last dot to the end.
- Return (root, ext), either part may be empty."""
- root, ext = '', ''
- for c in p:
- if c in ['/','\\']:
- root, ext = root + ext + c, ''
- elif c == '.':
- if ext:
- root, ext = root + ext, c
- else:
- ext = c
- elif ext:
- ext = ext + c
- else:
- root = root + c
- return root, ext
-
-
# Return the tail (basename) part of a path.
def basename(p):
@@ -168,84 +97,12 @@ def dirname(p):
return split(p)[0]
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-# Is a path a symbolic link?
-# This will always return false on systems where posix.lstat doesn't exist.
-
-def islink(path):
- """Test for symbolic link. On OS/2 always returns false"""
- return False
-
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
# Is a path a directory?
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
@@ -258,131 +115,6 @@ def ismount(path):
return len(p) == 1 and p[0] in '/\\'
-# Directory tree walk.
-# For each directory under top (including top itself, but excluding
-# '.' and '..'), func(arg, dirname, filenames) is called, where
-# dirname is the name of the directory and filenames is the list
-# of files (and subdirectories etc.) in the directory.
-# The func may modify the filenames list, to implement a filter,
-# or to impose a different order of visiting.
-
-def walk(top, func, arg):
- """Directory tree walk whth callback function.
-
- walk(top, func, arg) calls func(arg, d, files) for each directory d
- in the tree rooted at top (including top itself); files is a list
- of all the files and subdirs in directory d."""
- try:
- names = os.listdir(top)
- except os.error:
- return
- func(arg, top, names)
- exceptions = ('.', '..')
- for name in names:
- if name not in exceptions:
- name = join(top, name)
- if isdir(name):
- walk(name, func, arg)
-
-
-# Expand paths beginning with '~' or '~user'.
-# '~' means $HOME; '~user' means that user's home directory.
-# If the path doesn't begin with '~', or if the user or $HOME is unknown,
-# the path is returned unchanged (leaving error reporting to whatever
-# function is called with the expanded path as argument).
-# See also module 'glob' for expansion of *, ? and [...] in pathnames.
-# (A function should also be defined to do full *sh-style environment
-# variable expansion.)
-
-def expanduser(path):
- """Expand ~ and ~user constructs.
-
- If user or $HOME is unknown, do nothing."""
- if path[:1] != '~':
- return path
- i, n = 1, len(path)
- while i < n and path[i] not in '/\\':
- i = i + 1
- if i == 1:
- if 'HOME' in os.environ:
- userhome = os.environ['HOME']
- elif not 'HOMEPATH' in os.environ:
- return path
- else:
- try:
- drive = os.environ['HOMEDRIVE']
- except KeyError:
- drive = ''
- userhome = join(drive, os.environ['HOMEPATH'])
- else:
- return path
- return userhome + path[i:]
-
-
-# Expand paths containing shell variable substitutions.
-# The following rules apply:
-# - no expansion within single quotes
-# - no escape character, except for '$$' which is translated into '$'
-# - ${varname} is accepted.
-# - varnames can be made out of letters, digits and the character '_'
-# XXX With COMMAND.COM you can use any characters in a variable name,
-# XXX except '^|<>='.
-
-def expandvars(path):
- """Expand shell variables of form $var and ${var}.
-
- Unknown variables are left unchanged."""
- if '$' not in path:
- return path
- import string
- varchars = string.letters + string.digits + '_-'
- res = ''
- index = 0
- pathlen = len(path)
- while index < pathlen:
- c = path[index]
- if c == '\'': # no expansion within single quotes
- path = path[index + 1:]
- pathlen = len(path)
- try:
- index = path.index('\'')
- res = res + '\'' + path[:index + 1]
- except ValueError:
- res = res + path
- index = pathlen - 1
- elif c == '$': # variable or '$$'
- if path[index + 1:index + 2] == '$':
- res = res + c
- index = index + 1
- elif path[index + 1:index + 2] == '{':
- path = path[index+2:]
- pathlen = len(path)
- try:
- index = path.index('}')
- var = path[:index]
- if var in os.environ:
- res = res + os.environ[var]
- except ValueError:
- res = res + path
- index = pathlen - 1
- else:
- var = ''
- index = index + 1
- c = path[index:index + 1]
- while c != '' and c in varchars:
- var = var + c
- index = index + 1
- c = path[index:index + 1]
- if var in os.environ:
- res = res + os.environ[var]
- if c != '':
- res = res + c
- else:
- res = res + c
- index = index + 1
- return res
-
-
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
def normpath(path):
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 2bc836f..88303d0 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -28,7 +28,7 @@ def raw_input(prompt):
return sys.stdin.readline()
def find_function(funcname, filename):
- cre = re.compile(r'def\s+%s\s*[(]' % funcname)
+ cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname))
try:
fp = open(filename)
except IOError:
diff --git a/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py b/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
index 5d02ea3..773d1d7 100644
--- a/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
+++ b/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
@@ -301,7 +301,7 @@ class AppleScript_Suite_Events:
return _arguments['----']
def as_(self, _object, _attributes={}, **_arguments):
- """as_: Coercion
+ """as: Coercion
Required argument: an AE object reference
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: anything
diff --git a/Lib/plat-sunos5/STROPTS.py b/Lib/plat-sunos5/STROPTS.py
index e95db93..4970bd7 100644
--- a/Lib/plat-sunos5/STROPTS.py
+++ b/Lib/plat-sunos5/STROPTS.py
@@ -1550,7 +1550,7 @@ IE_NOMEM = -1
AS_PAGLCK = 0x80
AS_CLAIMGAP = 0x40
AS_UNMAPWAIT = 0x20
-def AS_TYPE_64BIT(as): return \
+def AS_TYPE_64BIT(as_): return \
AS_LREP_LINKEDLIST = 0
AS_LREP_SKIPLIST = 1
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index 9eac6bc..1521236 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -12,6 +12,7 @@ for manipulation of the pathname component of URLs.
import os
import stat
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -105,50 +106,24 @@ def splitdrive(p):
return '', p
-# Return the tail (basename) part of a path.
+# Return the tail (basename) part of a path, same as split(path)[1].
def basename(p):
"""Returns the final component of a pathname"""
- return split(p)[1]
+ i = p.rfind('/') + 1
+ return p[i:]
-# Return the head (dirname) part of a path.
+# Return the head (dirname) part of a path, same as split(path)[0].
def dirname(p):
"""Returns the directory component of a pathname"""
- return split(p)[0]
-
-
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
+ i = p.rfind('/') + 1
+ head = p[:i]
+ if head and head != '/'*len(head):
+ head = head.rstrip('/')
+ return head
-def getctime(filename):
- """Return the metadata change time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
# Is a path a symbolic link?
# This will always return false on systems where os.lstat doesn't exist.
@@ -161,19 +136,6 @@ def islink(path):
return False
return stat.S_ISLNK(st.st_mode)
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists. Returns False for broken symbolic links"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
-
# Being true for dangling symbolic links is also useful.
def lexists(path):
@@ -185,32 +147,6 @@ def lexists(path):
return True
-# Is a path a directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isfile() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Are two filenames really pointing to the same file?
def samefile(f1, f2):
@@ -328,8 +264,7 @@ def expanduser(path):
except KeyError:
return path
userhome = pwent.pw_dir
- if userhome.endswith('/'):
- i += 1
+ userhome = userhome.rstrip('/')
return userhome + path[i:]
diff --git a/Lib/pstats.py b/Lib/pstats.py
index 2acdadc..ba0b804 100644
--- a/Lib/pstats.py
+++ b/Lib/pstats.py
@@ -116,7 +116,7 @@ class Stats:
def load_stats(self, arg):
if not arg: self.stats = {}
- elif type(arg) == type(""):
+ elif isinstance(arg, basestring):
f = open(arg, 'rb')
self.stats = marshal.load(f)
f.close()
diff --git a/Lib/pty.py b/Lib/pty.py
index fae162d..889113c 100644
--- a/Lib/pty.py
+++ b/Lib/pty.py
@@ -118,6 +118,10 @@ def fork():
if (slave_fd > STDERR_FILENO):
os.close (slave_fd)
+ # Explicitly open the tty to make it become a controlling tty.
+ tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR)
+ os.close(tmp_fd)
+
# Parent and child process.
return pid, master_fd
diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py
index 0731224..079b38c 100644
--- a/Lib/pyclbr.py
+++ b/Lib/pyclbr.py
@@ -172,7 +172,7 @@ def _readmodule(module, path, inpackage=None):
# else it's a nested def
else:
# it's a function
- dict[meth_name] = Function(module, meth_name, file, lineno)
+ dict[meth_name] = Function(fullmodule, meth_name, file, lineno)
stack.append((None, thisindent)) # Marker for nested fns
elif token == 'class':
lineno, thisindent = start
diff --git a/Lib/sgmllib.py b/Lib/sgmllib.py
index 3020d11..3ab57c2 100644
--- a/Lib/sgmllib.py
+++ b/Lib/sgmllib.py
@@ -29,12 +29,7 @@ starttagopen = re.compile('<[>a-zA-Z]')
shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
piclose = re.compile('>')
-starttag = re.compile(r'<[a-zA-Z][-_.:a-zA-Z0-9]*\s*('
- r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
- r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~@]'
- r'[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*(?=[\s>/<])))?'
- r')*\s*/?\s*(?=[<>])')
-endtag = re.compile(r'</?[a-zA-Z][-_.:a-zA-Z0-9]*\s*/?\s*(?=[<>])')
+endbracket = re.compile('[<>]')
tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
attrfind = re.compile(
r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
@@ -254,10 +249,14 @@ class SGMLParser(markupbase.ParserBase):
self.finish_shorttag(tag, data)
self.__starttag_text = rawdata[start_pos:match.end(1) + 1]
return k
- match = starttag.match(rawdata, i)
+ # XXX The following should skip matching quotes (' or ")
+ # As a shortcut way to exit, this isn't so bad, but shouldn't
+ # be used to locate the actual end of the start tag since the
+ # < or > characters may be embedded in an attribute value.
+ match = endbracket.search(rawdata, i+1)
if not match:
return -1
- j = match.end(0)
+ j = match.start(0)
# Now parse the data between i+1 and j into a tag and attrs
attrs = []
if rawdata[i:i+2] == '<>':
@@ -306,10 +305,10 @@ class SGMLParser(markupbase.ParserBase):
# Internal -- parse endtag
def parse_endtag(self, i):
rawdata = self.rawdata
- match = endtag.match(rawdata, i)
+ match = endbracket.search(rawdata, i+1)
if not match:
return -1
- j = match.end(0)
+ j = match.start(0)
tag = rawdata[i+2:j].strip().lower()
if rawdata[j] == '>':
j = j+1
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index 9c8c4fa..a7305ce 100755
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -52,9 +52,10 @@ from sys import stderr
__all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
"SMTPSenderRefused","SMTPRecipientsRefused","SMTPDataError",
"SMTPConnectError","SMTPHeloError","SMTPAuthenticationError",
- "quoteaddr","quotedata","SMTP"]
+ "quoteaddr","quotedata","SMTP","SMTP_SSL"]
SMTP_PORT = 25
+SMTP_SSL_PORT = 465
CRLF="\r\n"
OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
@@ -240,6 +241,7 @@ class SMTP:
"""
self.esmtp_features = {}
+ self.default_port = SMTP_PORT
if host:
(code, msg) = self.connect(host, port)
if code != 220:
@@ -271,6 +273,13 @@ class SMTP:
"""
self.debuglevel = debuglevel
+ def _get_socket(self,af, socktype, proto,sa):
+ # This makes it simpler for SMTP_SSL to use the SMTP connect code
+ # and just alter the socket connection bit.
+ self.sock = socket.socket(af, socktype, proto)
+ if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
+ self.sock.connect(sa)
+
def connect(self, host='localhost', port = 0):
"""Connect to a host on a given port.
@@ -289,16 +298,14 @@ class SMTP:
try: port = int(port)
except ValueError:
raise socket.error, "nonnumeric port"
- if not port: port = SMTP_PORT
+ if not port: port = self.default_port
if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
msg = "getaddrinfo returns an empty list"
self.sock = None
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
- self.sock = socket.socket(af, socktype, proto)
- if self.debuglevel > 0: print>>stderr, 'connect:', sa
- self.sock.connect(sa)
+ self._get_socket(af,socktype,proto,sa)
except socket.error, msg:
if self.debuglevel > 0: print>>stderr, 'connect fail:', msg
if self.sock:
@@ -716,6 +723,28 @@ class SMTP:
self.docmd("quit")
self.close()
+class SMTP_SSL(SMTP):
+ """ This is a subclass derived from SMTP that connects over an SSL encrypted
+ socket (to use this class you need a socket module that was compiled with SSL
+ support). If host is not specified, '' (the local host) is used. If port is
+ omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile
+ are also optional - they can contain a PEM formatted private key and
+ certificate chain file for the SSL connection.
+ """
+ def __init__(self, host = '', port = 0, local_hostname = None,
+ keyfile = None, certfile = None):
+ self.keyfile = keyfile
+ self.certfile = certfile
+ SMTP.__init__(self,host,port,local_hostname)
+ self.default_port = SMTP_SSL_PORT
+
+ def _get_socket(self,af, socktype, proto,sa):
+ self.sock = socket.socket(af, socktype, proto)
+ if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
+ self.sock.connect(sa)
+ sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
+ self.sock = SSLFakeSocket(self.sock, sslobj)
+ self.file = SSLFakeFile(sslobj)
# Test the sendmail method, which tests most of the others.
# Note: This always sends to localhost.
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 55e267f..68ab05e 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -966,6 +966,8 @@ class Popen(object):
if isinstance(args, types.StringTypes):
args = [args]
+ else:
+ args = list(args)
if shell:
args = ["/bin/sh", "-c"] + args
@@ -1001,14 +1003,10 @@ class Popen(object):
if errwrite:
os.dup2(errwrite, 2)
- # Close pipe fds. Make sure we doesn't close the same
- # fd more than once.
- if p2cread:
- os.close(p2cread)
- if c2pwrite and c2pwrite not in (p2cread,):
- os.close(c2pwrite)
- if errwrite and errwrite not in (p2cread, c2pwrite):
- os.close(errwrite)
+ # Close pipe fds. Make sure we don't close the same
+ # fd more than once, or standard fds.
+ for fd in set((p2cread, c2pwrite, errwrite))-set((0,1,2)):
+ if fd: os.close(fd)
# Close all other fds, if asked for
if close_fds:
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index d238063..14553a7 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -49,6 +49,7 @@ import stat
import errno
import time
import struct
+import copy
if sys.platform == 'mac':
# This module needs work for MacOS9, especially in the area of pathname
@@ -138,7 +139,7 @@ TOEXEC = 0001 # execute/search by other
def stn(s, length):
"""Convert a python string to a null-terminated string buffer.
"""
- return s[:length-1] + (length - len(s) - 1) * NUL + NUL
+ return s[:length] + (length - len(s)) * NUL
def nti(s):
"""Convert a number field to a python number.
@@ -146,7 +147,7 @@ def nti(s):
# There are two possible encodings for a number field, see
# itn() below.
if s[0] != chr(0200):
- n = int(s.rstrip(NUL) or "0", 8)
+ n = int(s.rstrip(NUL + " ") or "0", 8)
else:
n = 0L
for i in xrange(len(s) - 1):
@@ -795,7 +796,6 @@ class TarInfo(object):
"""Construct a TarInfo object. name is the optional name
of the member.
"""
-
self.name = name # member name (dirnames must end with '/')
self.mode = 0666 # file permissions
self.uid = 0 # user id
@@ -809,8 +809,6 @@ class TarInfo(object):
self.gname = "group" # group name
self.devmajor = 0 # device major number
self.devminor = 0 # device minor number
- self.prefix = "" # prefix to filename or information
- # about sparse files
self.offset = 0 # the tar header starts here
self.offset_data = 0 # the file's data starts here
@@ -842,24 +840,74 @@ class TarInfo(object):
tarinfo.gname = buf[297:329].rstrip(NUL)
tarinfo.devmajor = nti(buf[329:337])
tarinfo.devminor = nti(buf[337:345])
- tarinfo.prefix = buf[345:500]
+ prefix = buf[345:500].rstrip(NUL)
+
+ if prefix and not tarinfo.issparse():
+ tarinfo.name = prefix + "/" + tarinfo.name
if tarinfo.chksum not in calc_chksums(buf):
raise ValueError("invalid header")
return tarinfo
def tobuf(self, posix=False):
- """Return a tar header block as a 512 byte string.
+ """Return a tar header as a string of 512 byte blocks.
"""
+ buf = ""
+ type = self.type
+ prefix = ""
+
+ if self.name.endswith("/"):
+ type = DIRTYPE
+
+ if type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
+ # Prevent "././@LongLink" from being normalized.
+ name = self.name
+ else:
+ name = normpath(self.name)
+
+ if type == DIRTYPE:
+ # directories should end with '/'
+ name += "/"
+
+ linkname = self.linkname
+ if linkname:
+ # if linkname is empty we end up with a '.'
+ linkname = normpath(linkname)
+
+ if posix:
+ if self.size > MAXSIZE_MEMBER:
+ raise ValueError("file is too large (>= 8 GB)")
+
+ if len(self.linkname) > LENGTH_LINK:
+ raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
+
+ if len(name) > LENGTH_NAME:
+ prefix = name[:LENGTH_PREFIX + 1]
+ while prefix and prefix[-1] != "/":
+ prefix = prefix[:-1]
+
+ name = name[len(prefix):]
+ prefix = prefix[:-1]
+
+ if not prefix or len(name) > LENGTH_NAME:
+ raise ValueError("name is too long")
+
+ else:
+ if len(self.linkname) > LENGTH_LINK:
+ buf += self._create_gnulong(self.linkname, GNUTYPE_LONGLINK)
+
+ if len(name) > LENGTH_NAME:
+ buf += self._create_gnulong(name, GNUTYPE_LONGNAME)
+
parts = [
- stn(self.name, 100),
+ stn(name, 100),
itn(self.mode & 07777, 8, posix),
itn(self.uid, 8, posix),
itn(self.gid, 8, posix),
itn(self.size, 12, posix),
itn(self.mtime, 12, posix),
" ", # checksum field
- self.type,
+ type,
stn(self.linkname, 100),
stn(MAGIC, 6),
stn(VERSION, 2),
@@ -867,15 +915,38 @@ class TarInfo(object):
stn(self.gname, 32),
itn(self.devmajor, 8, posix),
itn(self.devminor, 8, posix),
- stn(self.prefix, 155)
+ stn(prefix, 155)
]
- buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts))
- chksum = calc_chksums(buf)[0]
- buf = buf[:148] + "%06o\0" % chksum + buf[155:]
+ buf += struct.pack("%ds" % BLOCKSIZE, "".join(parts))
+ chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
+ buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
self.buf = buf
return buf
+ def _create_gnulong(self, name, type):
+ """Create a GNU longname/longlink header from name.
+ It consists of an extended tar header, with the length
+ of the longname as size, followed by data blocks,
+ which contain the longname as a null terminated string.
+ """
+ name += NUL
+
+ tarinfo = self.__class__()
+ tarinfo.name = "././@LongLink"
+ tarinfo.type = type
+ tarinfo.mode = 0
+ tarinfo.size = len(name)
+
+ # create extended header
+ buf = tarinfo.tobuf()
+ # create name blocks
+ buf += name
+ blocks, remainder = divmod(len(name), BLOCKSIZE)
+ if remainder > 0:
+ buf += (BLOCKSIZE - remainder) * NUL
+ return buf
+
def isreg(self):
return self.type in REGULAR_TYPES
def isfile(self):
@@ -1379,50 +1450,11 @@ class TarFile(object):
"""
self._check("aw")
- tarinfo.name = normpath(tarinfo.name)
- if tarinfo.isdir():
- # directories should end with '/'
- tarinfo.name += "/"
-
- if tarinfo.linkname:
- tarinfo.linkname = normpath(tarinfo.linkname)
-
- if tarinfo.size > MAXSIZE_MEMBER:
- if self.posix:
- raise ValueError("file is too large (>= 8 GB)")
- else:
- self._dbg(2, "tarfile: Created GNU tar largefile header")
-
-
- if len(tarinfo.linkname) > LENGTH_LINK:
- if self.posix:
- raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
- else:
- self._create_gnulong(tarinfo.linkname, GNUTYPE_LONGLINK)
- tarinfo.linkname = tarinfo.linkname[:LENGTH_LINK -1]
- self._dbg(2, "tarfile: Created GNU tar extension LONGLINK")
-
- if len(tarinfo.name) > LENGTH_NAME:
- if self.posix:
- prefix = tarinfo.name[:LENGTH_PREFIX + 1]
- while prefix and prefix[-1] != "/":
- prefix = prefix[:-1]
-
- name = tarinfo.name[len(prefix):]
- prefix = prefix[:-1]
-
- if not prefix or len(name) > LENGTH_NAME:
- raise ValueError("name is too long (>%d)" % (LENGTH_NAME))
-
- tarinfo.name = name
- tarinfo.prefix = prefix
- else:
- self._create_gnulong(tarinfo.name, GNUTYPE_LONGNAME)
- tarinfo.name = tarinfo.name[:LENGTH_NAME - 1]
- self._dbg(2, "tarfile: Created GNU tar extension LONGNAME")
+ tarinfo = copy.copy(tarinfo)
- self.fileobj.write(tarinfo.tobuf(self.posix))
- self.offset += BLOCKSIZE
+ buf = tarinfo.tobuf(self.posix)
+ self.fileobj.write(buf)
+ self.offset += len(buf)
# If there's data to follow, append it.
if fileobj is not None:
@@ -1781,12 +1813,6 @@ class TarFile(object):
if tarinfo.isreg() and tarinfo.name.endswith("/"):
tarinfo.type = DIRTYPE
- # The prefix field is used for filenames > 100 in
- # the POSIX standard.
- # name = prefix + '/' + name
- tarinfo.name = normpath(os.path.join(tarinfo.prefix.rstrip(NUL),
- tarinfo.name))
-
# Directory names should have a '/' at the end.
if tarinfo.isdir():
tarinfo.name += "/"
@@ -1911,10 +1937,6 @@ class TarFile(object):
self.offset += self._block(tarinfo.size)
tarinfo.size = origsize
- # Clear the prefix field so that it is not used
- # as a pathname in next().
- tarinfo.prefix = ""
-
return tarinfo
#--------------------------------------------------------------------------
@@ -1972,31 +1994,6 @@ class TarFile(object):
else:
return TarIter(self)
- def _create_gnulong(self, name, type):
- """Write a GNU longname/longlink member to the TarFile.
- It consists of an extended tar header, with the length
- of the longname as size, followed by data blocks,
- which contain the longname as a null terminated string.
- """
- name += NUL
-
- tarinfo = TarInfo()
- tarinfo.name = "././@LongLink"
- tarinfo.type = type
- tarinfo.mode = 0
- tarinfo.size = len(name)
-
- # write extended header
- self.fileobj.write(tarinfo.tobuf())
- self.offset += BLOCKSIZE
- # write name blocks
- self.fileobj.write(name)
- blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
- if remainder > 0:
- self.fileobj.write(NUL * (BLOCKSIZE - remainder))
- blocks += 1
- self.offset += blocks * BLOCKSIZE
-
def _dbg(self, level, msg):
"""Write debugging output to sys.stderr.
"""
diff --git a/Lib/test/README b/Lib/test/README
index 496c400..27f696c 100644
--- a/Lib/test/README
+++ b/Lib/test/README
@@ -379,8 +379,8 @@ test_support provides the following useful objects:
point numbers when you expect them to only be approximately equal
withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6).
- * ``check_syntax(statement)`` - make sure that the statement is *not*
- correct Python syntax.
+ * ``check_syntax_error(testcase, statement)`` - make sure that the
+ statement is *not* correct Python syntax.
Python and C statement coverage results are currently available at
diff --git a/Lib/test/crashers/bogus_sre_bytecode.py b/Lib/test/crashers/bogus_sre_bytecode.py
new file mode 100644
index 0000000..4bfc730
--- /dev/null
+++ b/Lib/test/crashers/bogus_sre_bytecode.py
@@ -0,0 +1,47 @@
+"""
+The regular expression engine in '_sre' can segfault when interpreting
+bogus bytecode.
+
+It is unclear whether this is a real bug or a "won't fix" case like
+bogus_code_obj.py, because it requires bytecode that is built by hand,
+as opposed to compiled by 're' from a string-source regexp. The
+difference with bogus_code_obj, though, is that the only existing regexp
+compiler is written in Python, so that the C code has no choice but
+accept arbitrary bytecode from Python-level.
+
+The test below builds and runs random bytecodes until 'match' crashes
+Python. I have not investigated why exactly segfaults occur nor how
+hard they would be to fix. Here are a few examples of 'code' that
+segfault for me:
+
+ [21, 50814, 8, 29, 16]
+ [21, 3967, 26, 10, 23, 54113]
+ [29, 23, 0, 2, 5]
+ [31, 64351, 0, 28, 3, 22281, 20, 4463, 9, 25, 59154, 15245, 2,
+ 16343, 3, 11600, 24380, 10, 37556, 10, 31, 15, 31]
+
+Here is also a 'code' that triggers an infinite uninterruptible loop:
+
+ [29, 1, 8, 21, 1, 43083, 6]
+
+"""
+
+import _sre, random
+
+def pick():
+ n = random.randrange(-65536, 65536)
+ if n < 0:
+ n &= 31
+ return n
+
+ss = ["", "world", "x" * 500]
+
+while 1:
+ code = [pick() for i in range(random.randrange(5, 25))]
+ print code
+ pat = _sre.compile(None, 0, code)
+ for s in ss:
+ try:
+ pat.match(s)
+ except RuntimeError:
+ pass
diff --git a/Lib/test/crashers/infinite_loop_re.py b/Lib/test/crashers/infinite_loop_re.py
new file mode 100644
index 0000000..9aecc56
--- /dev/null
+++ b/Lib/test/crashers/infinite_loop_re.py
@@ -0,0 +1,16 @@
+
+# This was taken from http://python.org/sf/1541697
+# It's not technically a crasher. It may not even truly be infinite,
+# however, I haven't waited a long time to see the result. It takes
+# 100% of CPU while running this and should be fixed.
+
+import re
+starttag = re.compile(r'<[a-zA-Z][-_.:a-zA-Z0-9]*\s*('
+ r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
+ r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~@]'
+ r'[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*(?=[\s>/<])))?'
+ r')*\s*/?\s*(?=[<>])')
+
+if __name__ == '__main__':
+ foo = '<table cellspacing="0" cellpadding="0" style="border-collapse'
+ starttag.match(foo)
diff --git a/Lib/test/crashers/loosing_mro_ref.py b/Lib/test/crashers/loosing_mro_ref.py
new file mode 100644
index 0000000..f0b8047
--- /dev/null
+++ b/Lib/test/crashers/loosing_mro_ref.py
@@ -0,0 +1,36 @@
+"""
+There is a way to put keys of any type in a type's dictionary.
+I think this allows various kinds of crashes, but so far I have only
+found a convoluted attack of _PyType_Lookup(), which uses the mro of the
+type without holding a strong reference to it. Probably works with
+super.__getattribute__() too, which uses the same kind of code.
+"""
+
+class MyKey(object):
+ def __hash__(self):
+ return hash('mykey')
+
+ def __cmp__(self, other):
+ # the following line decrefs the previous X.__mro__
+ X.__bases__ = (Base2,)
+ # trash all tuples of length 3, to make sure that the items of
+ # the previous X.__mro__ are really garbage
+ z = []
+ for i in range(1000):
+ z.append((i, None, None))
+ return -1
+
+
+class Base(object):
+ mykey = 'from Base'
+
+class Base2(object):
+ mykey = 'from Base2'
+
+class X(Base):
+ # you can't add a non-string key to X.__dict__, but it can be
+ # there from the beginning :-)
+ locals()[MyKey()] = 5
+
+print X.mykey
+# I get a segfault, or a slightly wrong assertion error in a debug build.
diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py
index 453c51c..fc1a6c3 100644
--- a/Lib/test/list_tests.py
+++ b/Lib/test/list_tests.py
@@ -269,7 +269,6 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(TypeError, a.insert)
def test_pop(self):
- from decimal import Decimal
a = self.type2test([-1, 0, 1])
a.pop()
self.assertEqual(a, [-1, 0])
@@ -281,8 +280,6 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(IndexError, a.pop)
self.assertRaises(TypeError, a.pop, 42, 42)
a = self.type2test([0, 10, 20, 30, 40])
- self.assertEqual(a.pop(Decimal(2)), 20)
- self.assertRaises(IndexError, a.pop, Decimal(25))
def test_remove(self):
a = self.type2test([0, 0, 1])
diff --git a/Lib/test/output/test_MimeWriter b/Lib/test/output/test_MimeWriter
deleted file mode 100644
index 9b97d93..0000000
--- a/Lib/test/output/test_MimeWriter
+++ /dev/null
@@ -1,110 +0,0 @@
-test_MimeWriter
-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--
diff --git a/Lib/test/output/test_cgi b/Lib/test/output/test_cgi
deleted file mode 100644
index 26eddfa..0000000
--- a/Lib/test/output/test_cgi
+++ /dev/null
@@ -1,42 +0,0 @@
-test_cgi
-'' => []
-'&' => []
-'&&' => []
-'=' => [('', '')]
-'=a' => [('', 'a')]
-'a' => [('a', '')]
-'a=' => [('a', '')]
-'a=' => [('a', '')]
-'&a=b' => [('a', 'b')]
-'a=a+b&b=b+c' => [('a', 'a b'), ('b', 'b c')]
-'a=1&a=2' => [('a', '1'), ('a', '2')]
-''
-'&'
-'&&'
-';'
-';&;'
-'='
-'=&='
-'=;='
-'=a'
-'&=a'
-'=a&'
-'=&a'
-'b=a'
-'b+=a'
-'a=b=a'
-'a=+b=a'
-'&b=a'
-'b&=a'
-'a=a+b&b=b+c'
-'a=a+b&a=b+a'
-'x=1&y=2.0&z=2-3.%2b0'
-'x=1;y=2.0&z=2-3.%2b0'
-'x=1;y=2.0;z=2-3.%2b0'
-'Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env'
-'group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse'
-Testing log
-Testing initlog 1
-Testing log 2
-Test FieldStorage methods that use readline
-Test basic FieldStorage multipart parsing
diff --git a/Lib/test/output/test_cookie b/Lib/test/output/test_cookie
deleted file mode 100644
index 95c7328..0000000
--- a/Lib/test/output/test_cookie
+++ /dev/null
@@ -1,32 +0,0 @@
-test_cookie
-<SimpleCookie: chips='ahoy' vienna='finger'>
-Set-Cookie: chips=ahoy
-Set-Cookie: vienna=finger
- chips 'ahoy' 'ahoy'
-Set-Cookie: chips=ahoy
- vienna 'finger' 'finger'
-Set-Cookie: vienna=finger
-<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\n;'>
-Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"
- keebler 'E=mc2; L="Loves"; fudge=\n;' 'E=mc2; L="Loves"; fudge=\n;'
-Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"
-<SimpleCookie: keebler='E=mc2'>
-Set-Cookie: keebler=E=mc2
- keebler 'E=mc2' 'E=mc2'
-Set-Cookie: keebler=E=mc2
-Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme
-
- <script type="text/javascript">
- <!-- begin hiding
- document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme; Version=1";
- // end hiding -->
- </script>
-
-
- <script type="text/javascript">
- <!-- begin hiding
- document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme";
- // end hiding -->
- </script>
-
-If anything blows up after this line, it's from Cookie's doctest.
diff --git a/Lib/test/output/test_global b/Lib/test/output/test_global
deleted file mode 100644
index a427a29..0000000
--- a/Lib/test/output/test_global
+++ /dev/null
@@ -1,5 +0,0 @@
-test_global
-got SyntaxError as expected
-got SyntaxError as expected
-got SyntaxError as expected
-as expected, no SyntaxError
diff --git a/Lib/test/output/test_grammar b/Lib/test/output/test_grammar
deleted file mode 100644
index 5033276..0000000
--- a/Lib/test/output/test_grammar
+++ /dev/null
@@ -1,69 +0,0 @@
-test_grammar
-1. Parser
-1.1 Tokens
-1.1.1 Backslashes
-1.1.2 Numeric literals
-1.1.2.1 Plain integers
-1.1.2.2 Long integers
-1.1.2.3 Floating point
-1.1.3 String literals
-1.1.4 Ellipsis literal
-1.2 Grammar
-single_input
-file_input
-expr_input
-eval_input
-funcdef
-lambdef
-simple_stmt
-expr_stmt
-print_stmt
-1 2 3
-1 2 3
-1 1 1
-extended print_stmt
-1 2 3
-1 2 3
-1 1 1
-hello world
-del_stmt
-pass_stmt
-flow_stmt
-break_stmt
-continue_stmt
-continue + try/except ok
-continue + try/finally ok
-testing continue and break in try/except in loop
-return_stmt
-yield_stmt
-raise_stmt
-import_name
-import_from
-global_stmt
-assert_stmt
-if_stmt
-while_stmt
-for_stmt
-try_stmt
-suite
-test
-comparison
-binary mask ops
-shift ops
-additive ops
-multiplicative ops
-unary ops
-selectors
-
-[1, (1,), (1, 2), (1, 2, 3)]
-atoms
-classdef
-['Apple', 'Banana', 'Coco nut']
-[3, 6, 9, 12, 15]
-[3, 4, 5]
-[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
-[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
-[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]
-[False, False, False]
-[[1, 2], [3, 4], [5, 6]]
-[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]
diff --git a/Lib/test/output/test_httplib b/Lib/test/output/test_httplib
deleted file mode 100644
index 302b876..0000000
--- a/Lib/test/output/test_httplib
+++ /dev/null
@@ -1,13 +0,0 @@
-test_httplib
-reply: 'HTTP/1.1 200 Ok\r\n'
-Text
-reply: 'HTTP/1.1 400.100 Not Ok\r\n'
-BadStatusLine raised as expected
-InvalidURL raised as expected
-InvalidURL raised as expected
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
-header: Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Content-Length: 14432
-
diff --git a/Lib/test/output/test_math b/Lib/test/output/test_math
deleted file mode 100644
index 4c8f77c..0000000
--- a/Lib/test/output/test_math
+++ /dev/null
@@ -1,28 +0,0 @@
-test_math
-math module, testing with eps 1e-05
-constants
-acos
-asin
-atan
-atan2
-ceil
-cos
-cosh
-degrees
-exp
-fabs
-floor
-fmod
-frexp
-hypot
-ldexp
-log
-log10
-modf
-pow
-radians
-sin
-sinh
-sqrt
-tan
-tanh
diff --git a/Lib/test/output/test_mmap b/Lib/test/output/test_mmap
deleted file mode 100644
index 605f840..0000000
--- a/Lib/test/output/test_mmap
+++ /dev/null
@@ -1,38 +0,0 @@
-test_mmap
-<type 'mmap.mmap'>
- Position of foo: 1.0 pages
- Length of file: 2.0 pages
- Contents of byte 0: '\x00'
- Contents of first 3 bytes: '\x00\x00\x00'
-
- Modifying file's content...
- Contents of byte 0: '3'
- Contents of first 3 bytes: '3\x00\x00'
- Contents of second page: '\x00foobar\x00'
- Regex match on mmap (page start, length of match): 1.0 6
- Seek to zeroth byte
- Seek to 42nd byte
- Seek to last byte
- Try to seek to negative position...
- Try to seek beyond end of mmap...
- Try to seek to negative position...
- Attempting resize()
- Creating 10 byte test data file.
- Opening mmap with access=ACCESS_READ
- Ensuring that readonly mmap can't be slice assigned.
- Ensuring that readonly mmap can't be item assigned.
- Ensuring that readonly mmap can't be write() to.
- Ensuring that readonly mmap can't be write_byte() to.
- Ensuring that readonly mmap can't be resized.
- Opening mmap with size too big
- Opening mmap with access=ACCESS_WRITE
- Modifying write-through memory map.
- Opening mmap with access=ACCESS_COPY
- Modifying copy-on-write memory map.
- Ensuring copy-on-write maps cannot be resized.
- Ensuring invalid access parameter raises exception.
- Try opening a bad file descriptor...
- Ensuring that passing 0 as map length sets map size to current file size.
- Ensuring that passing 0 as map length sets map size to current file size.
- anonymous mmap.mmap(-1, PAGESIZE)...
- Test passed
diff --git a/Lib/test/output/test_nis b/Lib/test/output/test_nis
deleted file mode 100644
index 0853ab4..0000000
--- a/Lib/test/output/test_nis
+++ /dev/null
@@ -1,2 +0,0 @@
-test_nis
-nis.maps()
diff --git a/Lib/test/output/test_opcodes b/Lib/test/output/test_opcodes
deleted file mode 100644
index 4685571..0000000
--- a/Lib/test/output/test_opcodes
+++ /dev/null
@@ -1,6 +0,0 @@
-test_opcodes
-2. Opcodes
-XXX Not yet fully implemented
-2.1 try inside for loop
-2.2 raise class exceptions
-2.3 comparing function objects
diff --git a/Lib/test/output/test_openpty b/Lib/test/output/test_openpty
deleted file mode 100644
index a8b8b5e..0000000
--- a/Lib/test/output/test_openpty
+++ /dev/null
@@ -1,2 +0,0 @@
-test_openpty
-Ping!
diff --git a/Lib/test/output/test_poll b/Lib/test/output/test_poll
deleted file mode 100644
index ca61d37..0000000
--- a/Lib/test/output/test_poll
+++ /dev/null
@@ -1,19 +0,0 @@
-test_poll
-Running poll test 1
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
-Poll test 1 complete
-Running poll test 2
-Poll test 2 complete
-Running poll test 3
-Poll test 3 complete
diff --git a/Lib/test/output/test_regex b/Lib/test/output/test_regex
deleted file mode 100644
index 1deb26f..0000000
--- a/Lib/test/output/test_regex
+++ /dev/null
@@ -1,29 +0,0 @@
-test_regex
-no match: -1
-successful search: 6
-caught expected exception
-failed awk syntax: -1
-successful awk syntax: 2
-failed awk syntax: -1
-matching with group names and compile()
--1
-caught expected exception
-matching with group names and symcomp()
-7
-801 999
-801
-('801', '999')
-('801', '999')
-realpat: \([0-9]+\) *\([0-9]+\)
-groupindex: {'one': 1, 'two': 2}
-not case folded search: -1
-case folded search: 6
-__members__: ['last', 'regs', 'translate', 'groupindex', 'realpat', 'givenpat']
-regs: ((6, 11), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1))
-last: HELLO WORLD
-translate: 256
-givenpat: world
-match with pos: -1
-search with pos: 18
-bogus group: ('world', None, None)
-no name: caught expected exception
diff --git a/Lib/test/output/test_scope b/Lib/test/output/test_scope
deleted file mode 100644
index a439e44..0000000
--- a/Lib/test/output/test_scope
+++ /dev/null
@@ -1,24 +0,0 @@
-test_scope
-1. simple nesting
-2. extra nesting
-3. simple nesting + rebinding
-4. nesting with global but no free
-5. nesting through class
-6. nesting plus free ref to global
-7. nearest enclosing scope
-8. mixed freevars and cellvars
-9. free variable in method
-10. recursion
-11. unoptimized namespaces
-12. lambdas
-13. UnboundLocal
-14. complex definitions
-15. scope of global statements
-16. check leaks
-17. class and global
-18. verify that locals() works
-19. var is bound and free in class
-20. interaction with trace function
-20. eval and exec with free variables
-21. list comprehension with local variables
-22. eval with free variables
diff --git a/Lib/test/output/test_tokenize b/Lib/test/output/test_tokenize
index 0c14308..4a3d58c 100644
--- a/Lib/test/output/test_tokenize
+++ b/Lib/test/output/test_tokenize
@@ -1,15 +1,23 @@
test_tokenize
-1,0-1,35: COMMENT "# Tests for the 'tokenize' module.\n"
-2,0-2,43: COMMENT '# Large bits stolen from test_grammar.py. \n'
+1,0-1,34: COMMENT "# Tests for the 'tokenize' module."
+1,34-1,35: NL '\n'
+2,0-2,42: COMMENT '# Large bits stolen from test_grammar.py. '
+2,42-2,43: NL '\n'
3,0-3,1: NL '\n'
-4,0-4,11: COMMENT '# Comments\n'
+4,0-4,10: COMMENT '# Comments'
+4,10-4,11: NL '\n'
5,0-5,3: STRING '"#"'
5,3-5,4: NEWLINE '\n'
-6,0-6,3: COMMENT "#'\n"
-7,0-7,3: COMMENT '#"\n'
-8,0-8,3: COMMENT '#\\\n'
-9,7-9,9: COMMENT '#\n'
-10,4-10,10: COMMENT '# abc\n'
+6,0-6,2: COMMENT "#'"
+6,2-6,3: NL '\n'
+7,0-7,2: COMMENT '#"'
+7,2-7,3: NL '\n'
+8,0-8,2: COMMENT '#\\'
+8,2-8,3: NL '\n'
+9,7-9,8: COMMENT '#'
+9,8-9,9: NL '\n'
+10,4-10,9: COMMENT '# abc'
+10,9-10,10: NL '\n'
11,0-12,4: STRING "'''#\n#'''"
12,4-12,5: NEWLINE '\n'
13,0-13,1: NL '\n'
@@ -19,7 +27,8 @@ test_tokenize
14,7-14,8: COMMENT '#'
14,8-14,9: NEWLINE '\n'
15,0-15,1: NL '\n'
-16,0-16,25: COMMENT '# Balancing continuation\n'
+16,0-16,24: COMMENT '# Balancing continuation'
+16,24-16,25: NL '\n'
17,0-17,1: NL '\n'
18,0-18,1: NAME 'a'
18,2-18,3: OP '='
@@ -93,7 +102,8 @@ test_tokenize
29,2-29,3: OP ')'
29,3-29,4: NEWLINE '\n'
30,0-30,1: NL '\n'
-31,0-31,37: COMMENT '# Backslash means line continuation:\n'
+31,0-31,36: COMMENT '# Backslash means line continuation:'
+31,36-31,37: NL '\n'
32,0-32,1: NAME 'x'
32,2-32,3: OP '='
32,4-32,5: NUMBER '1'
@@ -101,13 +111,15 @@ test_tokenize
33,2-33,3: NUMBER '1'
33,3-33,4: NEWLINE '\n'
34,0-34,1: NL '\n'
-35,0-35,55: COMMENT '# Backslash does not means continuation in comments :\\\n'
+35,0-35,54: COMMENT '# Backslash does not means continuation in comments :\\'
+35,54-35,55: NL '\n'
36,0-36,1: NAME 'x'
36,2-36,3: OP '='
36,4-36,5: NUMBER '0'
36,5-36,6: NEWLINE '\n'
37,0-37,1: NL '\n'
-38,0-38,20: COMMENT '# Ordinary integers\n'
+38,0-38,19: COMMENT '# Ordinary integers'
+38,19-38,20: NL '\n'
39,0-39,4: NUMBER '0xff'
39,5-39,7: OP '!='
39,8-39,11: NUMBER '255'
@@ -138,7 +150,8 @@ test_tokenize
44,15-44,16: NUMBER '1'
44,16-44,17: NEWLINE '\n'
45,0-45,1: NL '\n'
-46,0-46,16: COMMENT '# Long integers\n'
+46,0-46,15: COMMENT '# Long integers'
+46,15-46,16: NL '\n'
47,0-47,1: NAME 'x'
47,2-47,3: OP '='
47,4-47,6: NUMBER '0L'
@@ -172,7 +185,8 @@ test_tokenize
54,4-54,35: NUMBER '123456789012345678901234567890l'
54,35-54,36: NEWLINE '\n'
55,0-55,1: NL '\n'
-56,0-56,25: COMMENT '# Floating-point numbers\n'
+56,0-56,24: COMMENT '# Floating-point numbers'
+56,24-56,25: NL '\n'
57,0-57,1: NAME 'x'
57,2-57,3: OP '='
57,4-57,8: NUMBER '3.14'
@@ -185,7 +199,8 @@ test_tokenize
59,2-59,3: OP '='
59,4-59,9: NUMBER '0.314'
59,9-59,10: NEWLINE '\n'
-60,0-60,18: COMMENT '# XXX x = 000.314\n'
+60,0-60,17: COMMENT '# XXX x = 000.314'
+60,17-60,18: NL '\n'
61,0-61,1: NAME 'x'
61,2-61,3: OP '='
61,4-61,8: NUMBER '.314'
@@ -219,7 +234,8 @@ test_tokenize
68,4-68,9: NUMBER '3.1e4'
68,9-68,10: NEWLINE '\n'
69,0-69,1: NL '\n'
-70,0-70,18: COMMENT '# String literals\n'
+70,0-70,17: COMMENT '# String literals'
+70,17-70,18: NL '\n'
71,0-71,1: NAME 'x'
71,2-71,3: OP '='
71,4-71,6: STRING "''"
@@ -367,7 +383,8 @@ test_tokenize
125,6-126,3: STRING "uR'''spam\n'''"
126,3-126,4: NEWLINE '\n'
127,0-127,1: NL '\n'
-128,0-128,14: COMMENT '# Indentation\n'
+128,0-128,13: COMMENT '# Indentation'
+128,13-128,14: NL '\n'
129,0-129,2: NAME 'if'
129,3-129,4: NUMBER '1'
129,4-129,5: OP ':'
@@ -439,7 +456,8 @@ test_tokenize
142,14-142,15: NUMBER '2'
142,15-142,16: NEWLINE '\n'
143,0-143,1: NL '\n'
-144,0-144,12: COMMENT '# Operators\n'
+144,0-144,11: COMMENT '# Operators'
+144,11-144,12: NL '\n'
145,0-145,1: NL '\n'
146,0-146,0: DEDENT ''
146,0-146,0: DEDENT ''
@@ -501,7 +519,8 @@ test_tokenize
149,27-149,28: OP ')'
149,28-149,29: NEWLINE '\n'
150,0-150,1: NL '\n'
-151,0-151,13: COMMENT '# comparison\n'
+151,0-151,12: COMMENT '# comparison'
+151,12-151,13: NL '\n'
152,0-152,2: NAME 'if'
152,3-152,4: NUMBER '1'
152,5-152,6: OP '<'
@@ -532,7 +551,8 @@ test_tokenize
152,67-152,71: NAME 'pass'
152,71-152,72: NEWLINE '\n'
153,0-153,1: NL '\n'
-154,0-154,9: COMMENT '# binary\n'
+154,0-154,8: COMMENT '# binary'
+154,8-154,9: NL '\n'
155,0-155,1: NAME 'x'
155,2-155,3: OP '='
155,4-155,5: NUMBER '1'
@@ -552,7 +572,8 @@ test_tokenize
157,8-157,9: NUMBER '1'
157,9-157,10: NEWLINE '\n'
158,0-158,1: NL '\n'
-159,0-159,8: COMMENT '# shift\n'
+159,0-159,7: COMMENT '# shift'
+159,7-159,8: NL '\n'
160,0-160,1: NAME 'x'
160,2-160,3: OP '='
160,4-160,5: NUMBER '1'
@@ -562,7 +583,8 @@ test_tokenize
160,14-160,15: NUMBER '1'
160,15-160,16: NEWLINE '\n'
161,0-161,1: NL '\n'
-162,0-162,11: COMMENT '# additive\n'
+162,0-162,10: COMMENT '# additive'
+162,10-162,11: NL '\n'
163,0-163,1: NAME 'x'
163,2-163,3: OP '='
163,4-163,5: NUMBER '1'
@@ -576,7 +598,8 @@ test_tokenize
163,20-163,21: NUMBER '1'
163,21-163,22: NEWLINE '\n'
164,0-164,1: NL '\n'
-165,0-165,17: COMMENT '# multiplicative\n'
+165,0-165,16: COMMENT '# multiplicative'
+165,16-165,17: NL '\n'
166,0-166,1: NAME 'x'
166,2-166,3: OP '='
166,4-166,5: NUMBER '1'
@@ -588,7 +611,8 @@ test_tokenize
166,16-166,17: NUMBER '1'
166,17-166,18: NEWLINE '\n'
167,0-167,1: NL '\n'
-168,0-168,8: COMMENT '# unary\n'
+168,0-168,7: COMMENT '# unary'
+168,7-168,8: NL '\n'
169,0-169,1: NAME 'x'
169,2-169,3: OP '='
169,4-169,5: OP '~'
@@ -626,7 +650,8 @@ test_tokenize
170,24-170,25: NUMBER '1'
170,25-170,26: NEWLINE '\n'
171,0-171,1: NL '\n'
-172,0-172,11: COMMENT '# selector\n'
+172,0-172,10: COMMENT '# selector'
+172,10-172,11: NL '\n'
173,0-173,6: NAME 'import'
173,7-173,10: NAME 'sys'
173,10-173,11: OP ','
diff --git a/Lib/test/output/test_types b/Lib/test/output/test_types
deleted file mode 100644
index b49ce0d..0000000
--- a/Lib/test/output/test_types
+++ /dev/null
@@ -1,15 +0,0 @@
-test_types
-6. Built-in types
-6.1 Truth value testing
-6.2 Boolean operations
-6.3 Comparisons
-6.4 Numeric types (mostly conversions)
-6.4.1 32-bit integers
-6.4.2 Long integers
-6.4.3 Floating point numbers
-6.5 Sequence types
-6.5.1 Strings
-6.5.2 Tuples [see test_tuple.py]
-6.5.3 Lists [see test_list.py]
-6.6 Mappings == Dictionaries [see test_dict.py]
-Buffers
diff --git a/Lib/test/output/test_xdrlib b/Lib/test/output/test_xdrlib
deleted file mode 100644
index d86caa9..0000000
--- a/Lib/test/output/test_xdrlib
+++ /dev/null
@@ -1,19 +0,0 @@
-test_xdrlib
-pack test 0 succeeded
-pack test 1 succeeded
-pack test 2 succeeded
-pack test 3 succeeded
-pack test 4 succeeded
-pack test 5 succeeded
-pack test 6 succeeded
-pack test 7 succeeded
-pack test 8 succeeded
-unpack test 0 succeeded : 9
-unpack test 1 succeeded : True
-unpack test 2 succeeded : False
-unpack test 3 succeeded : 45
-unpack test 4 succeeded : 1.89999997616
-unpack test 5 succeeded : 1.9
-unpack test 6 succeeded : hello world
-unpack test 7 succeeded : [0, 1, 2, 3, 4]
-unpack test 8 succeeded : ['what', 'is', 'hapnin', 'doctor']
diff --git a/Lib/test/outstanding_bugs.py b/Lib/test/outstanding_bugs.py
index 7e37c85..04afcbd 100644
--- a/Lib/test/outstanding_bugs.py
+++ b/Lib/test/outstanding_bugs.py
@@ -9,19 +9,14 @@
import unittest
from test import test_support
-class TestBug1385040(unittest.TestCase):
- def testSyntaxError(self):
- import compiler
-
- # The following snippet gives a SyntaxError in the interpreter
- #
- # If you compile and exec it, the call foo(7) returns (7, 1)
- self.assertRaises(SyntaxError, compiler.compile,
- "def foo(a=1, b): return a, b\n\n", "<string>", "exec")
+#
+# No test cases for outstanding bugs at the moment.
+#
def test_main():
- test_support.run_unittest(TestBug1385040)
+ #test_support.run_unittest()
+ pass
if __name__ == "__main__":
test_main()
diff --git a/Lib/test/sgml_input.html b/Lib/test/sgml_input.html
new file mode 100644
index 0000000..f4d2e6c
--- /dev/null
+++ b/Lib/test/sgml_input.html
@@ -0,0 +1,212 @@
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+ <link rel="stylesheet" type="text/css" href="http://ogame182.de/epicblue/formate.css">
+ <script language="JavaScript" src="js/flotten.js"></script>
+ </head>
+ <body>
+ <script language=JavaScript> if (parent.frames.length == 0) { top.location.href = "http://es.ogame.org/"; } </script> <script language="JavaScript">
+function haha(z1) {
+ eval("location='"+z1.options[z1.selectedIndex].value+"'");
+}
+</script>
+<center>
+<table>
+ <tr>
+ <td></td>
+ <td>
+ <center>
+ <table>
+ <tr>
+ <td><img src="http://ogame182.de/epicblue/planeten/small/s_dschjungelplanet04.jpg" width="50" height="50"></td>
+ <td>
+ <table border="1">
+ <select size="1" onchange="haha(this)">
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=33875341&mode=Flotte&gid=&messageziel=&re=0" selected>Alien sex friend [2:250:6]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=33905100&mode=Flotte&gid=&messageziel=&re=0" >1989 [2:248:14]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=34570808&mode=Flotte&gid=&messageziel=&re=0" >1990 [2:248:6]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=34570858&mode=Flotte&gid=&messageziel=&re=0" >1991 [2:254:6]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=34572929&mode=Flotte&gid=&messageziel=&re=0" >Colonia [2:253:12]</option>
+ </select>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </center>
+ </td>
+ <td>
+ <table border="0" width="100%" cellspacing="0" cellpadding="0">
+ <tr>
+ <td align="center"></td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/metall.gif" width="42" height="22">
+ </td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/kristall.gif" width="42" height="22">
+ </td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/deuterium.gif" width="42" height="22">
+ </td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/energie.gif" width="42" height="22">
+ </td>
+ <td align="center"></td>
+ </tr>
+ <tr>
+ <td align="center"><i><b>&nbsp;&nbsp;</b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Metal</font></b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Cristal</font></b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Deuterio</font></b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Energía</font></b></i></td>
+ <td align="center"><i><b>&nbsp;&nbsp;</b></i></td>
+ </tr>
+ <tr>
+ <td align="center"></td>
+ <td align="center" width="85">160.636</td>
+ <td align="center" width="85">3.406</td>
+ <td align="center" width="85">39.230</td>
+ <td align="center" width="85"><font color=#ff0000>-80</font>/3.965</td>
+ <td align="center"></td>
+ </tr>
+ </table>
+ </tr>
+ </table>
+ </center>
+<br />
+ <script language="JavaScript">
+ <!--
+ function link_to_gamepay() {
+ self.location = "https://www.gamepay.de/?lang=es&serverID=8&userID=129360&gameID=ogame&gui=v2&chksum=a9751afa9e37e6b1b826356bcca45675";
+ }
+//-->
+ </script>
+<center>
+ <table width="519" border="0" cellpadding="0" cellspacing="1">
+ <tr height="20">
+ <td colspan="8" class="c">Flotas (max. 9)</td>
+ </tr>
+ <tr height="20">
+ <th>Num.</th>
+ <th>Misión</th>
+ <th>Cantidad</th>
+ <th>Comienzo</th>
+ <th>Salida</th>
+ <th>Objetivo</th>
+ <th>Llegada</th>
+ <th>Orden</th>
+ </tr>
+ <tr height="20">
+ <th>1</th>
+ <th>
+ <a title="">Espionaje</a>
+ <a title="Flota en el planeta">(F)</a>
+ </th>
+ <th> <a title="Sonda de espionaje: 3
+">3</a></th>
+ <th>[2:250:6]</th>
+ <th>Wed Aug 9 18:00:02</th>
+ <th>[2:242:5]</th>
+ <th>Wed Aug 9 18:01:02</th>
+ <th>
+ <form action="flotten1.php?session=8912ae912fec" method="POST">
+ <input type="hidden" name="order_return" value="25054490" />
+ <input type="submit" value="Enviar de regreso" />
+ </form>
+ </th>
+ </tr>
+ <tr height="20">
+ <th>2</th>
+ <th>
+ <a title="">Espionaje</a>
+ <a title="Volver al planeta">(V)</a>
+ </th>
+ <th> <a title="Sonda de espionaje: 3
+">3</a></th>
+ <th>[2:250:6]</th>
+ <th>Wed Aug 9 17:59:55</th>
+ <th>[2:242:1]</th>
+ <th>Wed Aug 9 18:01:55</th>
+ <th>
+ </th>
+ </tr>
+ </table>
+
+
+
+<form action="flotten2.php?session=8912ae912fec" method="POST">
+ <table width="519" border="0" cellpadding="0" cellspacing="1">
+ <tr height="20">
+ <td colspan="4" class="c">Nueva misión: elegir naves</td>
+ </tr>
+ <tr height="20">
+ <th>Naves</th>
+ <th>Disponibles</th>
+<!-- <th>Gesch.</th> -->
+ <th>-</th>
+ <th>-</th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 8500">Nave pequeña de carga</a></th>
+ <th>10<input type="hidden" name="maxship202" value="10"/></th>
+<!-- <th>8500 -->
+ <input type="hidden" name="consumption202" value="10"/>
+ <input type="hidden" name="speed202" value="8500" /></th>
+ <input type="hidden" name="capacity202" value="5000" /></th>
+ <th><a href="javascript:maxShip('ship202');" >máx</a> </th>
+ <th><input name="ship202" size="10" value="0" alt="Nave pequeña de carga 10"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 12750">Nave grande de carga</a></th>
+ <th>19<input type="hidden" name="maxship203" value="19"/></th>
+<!-- <th>12750 -->
+ <input type="hidden" name="consumption203" value="50"/>
+ <input type="hidden" name="speed203" value="12750" /></th>
+ <input type="hidden" name="capacity203" value="25000" /></th>
+ <th><a href="javascript:maxShip('ship203');" >máx</a> </th>
+ <th><input name="ship203" size="10" value="0" alt="Nave grande de carga 19"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 27000">Crucero</a></th>
+ <th>6<input type="hidden" name="maxship206" value="6"/></th>
+<!-- <th>27000 -->
+ <input type="hidden" name="consumption206" value="300"/>
+ <input type="hidden" name="speed206" value="27000" /></th>
+ <input type="hidden" name="capacity206" value="800" /></th>
+ <th><a href="javascript:maxShip('ship206');" >máx</a> </th>
+ <th><input name="ship206" size="10" value="0" alt="Crucero 6"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 3400">Reciclador</a></th>
+ <th>1<input type="hidden" name="maxship209" value="1"/></th>
+<!-- <th>3400 -->
+ <input type="hidden" name="consumption209" value="300"/>
+ <input type="hidden" name="speed209" value="3400" /></th>
+ <input type="hidden" name="capacity209" value="20000" /></th>
+ <th><a href="javascript:maxShip('ship209');" >máx</a> </th>
+ <th><input name="ship209" size="10" value="0" alt="Reciclador 1"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 170000000">Sonda de espionaje</a></th>
+ <th>139<input type="hidden" name="maxship210" value="139"/></th>
+<!-- <th>170000000 -->
+ <input type="hidden" name="consumption210" value="1"/>
+ <input type="hidden" name="speed210" value="170000000" /></th>
+ <input type="hidden" name="capacity210" value="5" /></th>
+ <th><a href="javascript:maxShip('ship210');" >máx</a> </th>
+ <th><input name="ship210" size="10" value="0" alt="Sonda de espionaje 139"/></th>
+ </tr>
+ <tr height="20">
+ <th colspan="2"><a href="javascript:noShips();" >Ninguna nave</a></th>
+ <th colspan="2"><a href="javascript:maxShips();" >Todas las naves</a></th>
+ </tr>
+ <tr height="20">
+ <th colspan="4"><input type="submit" value="Continuar" /></th>
+ </tr>
+<tr><th colspan=4>
+<iframe id='a44fb522' name='a44fb522' src='http://ads.gameforgeads.de/adframe.php?n=a44fb522&amp;what=zone:578' framespacing='0' frameborder='no' scrolling='no' width='468' height='60'></iframe>
+<br><center></center></br>
+</th></tr>
+</form>
+</table>
+ </body>
+</html>
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index 73447ad..1aa68de 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -1069,7 +1069,7 @@ class MixinStrUnicodeUserStringTest:
# from raymond's original specification
S = 'http://www.python.org'
self.checkequal(('http', '://', 'www.python.org'), S, 'rpartition', '://')
- self.checkequal(('http://www.python.org', '', ''), S, 'rpartition', '?')
+ self.checkequal(('', '', 'http://www.python.org'), S, 'rpartition', '?')
self.checkequal(('', 'http://', 'www.python.org'), S, 'rpartition', 'http://')
self.checkequal(('http://www.python.', 'org', ''), S, 'rpartition', 'org')
diff --git a/Lib/test/test_MimeWriter.py b/Lib/test/test_MimeWriter.py
index 5041105..feca163 100644
--- a/Lib/test/test_MimeWriter.py
+++ b/Lib/test/test_MimeWriter.py
@@ -7,6 +7,8 @@ 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
@@ -77,94 +79,213 @@ EXTERNAL_METADATA = [
]
-def main():
- import sys
+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
- # Toplevel headers
+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 = MimeWriter(sys.stdout)
- 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
- # 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")
- 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
- # First toplevel body part: metadata
+ md = toplevel.nextpart()
+ md.startmultipartbody("knowbot-metadata", "802spam999")
- md = toplevel.nextpart()
- md.startmultipartbody("knowbot-metadata", "802spam999")
+ # Metadata part 1
- # 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
- 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
- # 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
- 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
- # 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
- 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()
- md.lastpart()
+ # Second toplevel body part: code
- # Second toplevel body part: code
+ code = toplevel.nextpart()
+ code.startmultipartbody("knowbot-code", "803spam999")
- code = toplevel.nextpart()
- code.startmultipartbody("knowbot-code", "803spam999")
+ # Code: buyer program source
- # Code: buyer program source
+ buyer = code.nextpart()
+ buyer.addheader("KP-Module-Name", "BuyerKP")
+ f = buyer.startbody("text/plain")
+ f.write(BUYER)
- buyer = code.nextpart()
- buyer.addheader("KP-Module-Name", "BuyerKP")
- f = buyer.startbody("text/plain")
- f.write(BUYER)
+ code.lastpart()
- code.lastpart()
+ # Third toplevel body part: state
- # Third toplevel body part: state
+ state = toplevel.nextpart()
+ state.addheader("KP-Main-Module", "main")
+ state.startmultipartbody("knowbot-state", "804spam999")
- state = toplevel.nextpart()
- state.addheader("KP-Main-Module", "main")
- state.startmultipartbody("knowbot-state", "804spam999")
+ # State: a bunch of assignments
- # State: a bunch of assignments
+ st = state.nextpart()
+ st.addheader("KP-Module-Name", "main")
+ f = st.startbody("text/plain")
+ f.write(STATE)
- st = state.nextpart()
- st.addheader("KP-Module-Name", "main")
- f = st.startbody("text/plain")
- f.write(STATE)
+ state.lastpart()
- state.lastpart()
+ # End toplevel body parts
- # End toplevel body parts
+ toplevel.lastpart()
- toplevel.lastpart()
+ self.assertEqual(buf.getvalue(), OUTPUT)
+def test_main():
+ run_unittest(MimewriterTest)
-main()
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_StringIO.py b/Lib/test/test_StringIO.py
index cc3367f..9f79b02 100644
--- a/Lib/test/test_StringIO.py
+++ b/Lib/test/test_StringIO.py
@@ -62,6 +62,7 @@ class TestGenericStringIO(unittest.TestCase):
eq(f.getvalue(), 'abcde')
f.write('xyz')
eq(f.getvalue(), 'abcdexyz')
+ self.assertRaises(IOError, f.truncate, -1)
f.close()
self.assertRaises(ValueError, f.write, 'frobnitz')
@@ -120,6 +121,28 @@ class TestStringIO(TestGenericStringIO):
class TestcStringIO(TestGenericStringIO):
MODULE = cStringIO
+ def test_unicode(self):
+
+ if not test_support.have_unicode: return
+
+ # The cStringIO module converts Unicode strings to character
+ # strings when writing them to cStringIO objects.
+ # Check that this works.
+
+ f = self.MODULE.StringIO()
+ f.write(unicode(self._line[:5]))
+ s = f.getvalue()
+ self.assertEqual(s, 'abcde')
+ self.assertEqual(type(s), types.StringType)
+
+ f = self.MODULE.StringIO(unicode(self._line[:5]))
+ s = f.getvalue()
+ self.assertEqual(s, 'abcde')
+ self.assertEqual(type(s), types.StringType)
+
+ self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO,
+ unicode('\xf4', 'latin-1'))
+
import sys
if sys.platform.startswith('java'):
# Jython doesn't have a buffer object, so we just do a useless
diff --git a/Lib/test/test___future__.py b/Lib/test/test___future__.py
index 7d2b2ae..50a2c74 100644
--- a/Lib/test/test___future__.py
+++ b/Lib/test/test___future__.py
@@ -1,59 +1,63 @@
#! /usr/bin/env python
-from test.test_support import verbose, verify
-from types import TupleType, StringType, IntType
+import unittest
+from test import test_support
import __future__
GOOD_SERIALS = ("alpha", "beta", "candidate", "final")
features = __future__.all_feature_names
-# Verify that all_feature_names appears correct.
-given_feature_names = features[:]
-for name in dir(__future__):
- obj = getattr(__future__, name, None)
- if obj is not None and isinstance(obj, __future__._Feature):
- verify(name in given_feature_names,
- "%r should have been in all_feature_names" % name)
- given_feature_names.remove(name)
-verify(len(given_feature_names) == 0,
- "all_feature_names has too much: %r" % given_feature_names)
-del given_feature_names
-
-for feature in features:
- value = getattr(__future__, feature)
- if verbose:
- print "Checking __future__ ", feature, "value", value
-
- optional = value.getOptionalRelease()
- mandatory = value.getMandatoryRelease()
-
- verify(type(optional) is TupleType, "optional isn't tuple")
- verify(len(optional) == 5, "optional isn't 5-tuple")
- major, minor, micro, level, serial = optional
- verify(type(major) is IntType, "optional major isn't int")
- verify(type(minor) is IntType, "optional minor isn't int")
- verify(type(micro) is IntType, "optional micro isn't int")
- verify(isinstance(level, basestring), "optional level isn't string")
- verify(level in GOOD_SERIALS,
- "optional level string has unknown value")
- verify(type(serial) is IntType, "optional serial isn't int")
-
- verify(type(mandatory) is TupleType or
- mandatory is None, "mandatory isn't tuple or None")
- if mandatory is not None:
- verify(len(mandatory) == 5, "mandatory isn't 5-tuple")
- major, minor, micro, level, serial = mandatory
- verify(type(major) is IntType, "mandatory major isn't int")
- verify(type(minor) is IntType, "mandatory minor isn't int")
- verify(type(micro) is IntType, "mandatory micro isn't int")
- verify(isinstance(level, basestring), "mandatory level isn't string")
- verify(level in GOOD_SERIALS,
- "mandatory serial string has unknown value")
- verify(type(serial) is IntType, "mandatory serial isn't int")
- verify(optional < mandatory,
- "optional not less than mandatory, and mandatory not None")
-
- verify(hasattr(value, "compiler_flag"),
- "feature is missing a .compiler_flag attr")
- verify(type(getattr(value, "compiler_flag")) is IntType,
- ".compiler_flag isn't int")
+class FutureTest(unittest.TestCase):
+
+ def test_names(self):
+ # Verify that all_feature_names appears correct.
+ given_feature_names = features[:]
+ for name in dir(__future__):
+ obj = getattr(__future__, name, None)
+ if obj is not None and isinstance(obj, __future__._Feature):
+ self.assert_(
+ name in given_feature_names,
+ "%r should have been in all_feature_names" % name
+ )
+ given_feature_names.remove(name)
+ self.assertEqual(len(given_feature_names), 0,
+ "all_feature_names has too much: %r" % given_feature_names)
+
+ def test_attributes(self):
+ for feature in features:
+ value = getattr(__future__, feature)
+
+ optional = value.getOptionalRelease()
+ mandatory = value.getMandatoryRelease()
+
+ a = self.assert_
+ e = self.assertEqual
+ def check(t, name):
+ a(isinstance(t, tuple), "%s isn't tuple" % name)
+ e(len(t), 5, "%s isn't 5-tuple" % name)
+ (major, minor, micro, level, serial) = t
+ a(isinstance(major, int), "%s major isn't int" % name)
+ a(isinstance(minor, int), "%s minor isn't int" % name)
+ a(isinstance(micro, int), "%s micro isn't int" % name)
+ a(isinstance(level, basestring),
+ "%s level isn't string" % name)
+ a(level in GOOD_SERIALS,
+ "%s level string has unknown value" % name)
+ a(isinstance(serial, int), "%s serial isn't int" % name)
+
+ check(optional, "optional")
+ if mandatory is not None:
+ check(mandatory, "mandatory")
+ a(optional < mandatory,
+ "optional not less than mandatory, and mandatory not None")
+
+ a(hasattr(value, "compiler_flag"),
+ "feature is missing a .compiler_flag attr")
+ a(isinstance(getattr(value, "compiler_flag"), int),
+ ".compiler_flag isn't int")
+
+def test_main():
+ test_support.run_unittest(FutureTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index 6adbf33..5c79b48 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -85,6 +85,13 @@ class BaseTest(unittest.TestCase):
self.assertNotEqual(id(a), id(b))
self.assertEqual(a, b)
+ def test_deepcopy(self):
+ import copy
+ a = array.array(self.typecode, self.example)
+ b = copy.deepcopy(a)
+ self.assertNotEqual(id(a), id(b))
+ self.assertEqual(a, b)
+
def test_pickle(self):
for protocol in (0, 1, 2):
a = array.array(self.typecode, self.example)
diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py
index 8df4504..8272ad9 100755
--- a/Lib/test/test_binascii.py
+++ b/Lib/test/test_binascii.py
@@ -134,7 +134,7 @@ class BinASCIITest(unittest.TestCase):
pass
else:
self.fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError")
- self.assertEqual(binascii.a2b_qp("= "), "")
+ self.assertEqual(binascii.a2b_qp("= "), "= ")
self.assertEqual(binascii.a2b_qp("=="), "=")
self.assertEqual(binascii.a2b_qp("=AX"), "=AX")
self.assertRaises(TypeError, binascii.b2a_qp, foo="bar")
diff --git a/Lib/test/test_bufio.py b/Lib/test/test_bufio.py
index 611cd69..14a926a 100644
--- a/Lib/test/test_bufio.py
+++ b/Lib/test/test_bufio.py
@@ -1,60 +1,66 @@
-from test.test_support import verify, TestFailed, TESTFN
+import unittest
+from test import test_support
# Simple test to ensure that optimizations in fileobject.c deliver
# the expected results. For best testing, run this under a debug-build
# Python too (to exercise asserts in the C code).
-# Repeat string 'pattern' as often as needed to reach total length
-# 'length'. Then call try_one with that string, a string one larger
-# than that, and a string one smaller than that. The main driver
-# feeds this all small sizes and various powers of 2, so we exercise
-# all likely stdio buffer sizes, and "off by one" errors on both
-# sides.
-def drive_one(pattern, length):
- q, r = divmod(length, len(pattern))
- teststring = pattern * q + pattern[:r]
- verify(len(teststring) == length)
- try_one(teststring)
- try_one(teststring + "x")
- try_one(teststring[:-1])
-
-# Write s + "\n" + s to file, then open it and ensure that successive
-# .readline()s deliver what we wrote.
-def try_one(s):
- # Since C doesn't guarantee we can write/read arbitrary bytes in text
- # files, use binary mode.
- f = open(TESTFN, "wb")
- # write once with \n and once without
- f.write(s)
- f.write("\n")
- f.write(s)
- f.close()
- f = open(TESTFN, "rb")
- line = f.readline()
- if line != s + "\n":
- raise TestFailed("Expected %r got %r" % (s + "\n", line))
- line = f.readline()
- if line != s:
- raise TestFailed("Expected %r got %r" % (s, line))
- line = f.readline()
- if line:
- raise TestFailed("Expected EOF but got %r" % line)
- f.close()
-
-# A pattern with prime length, to avoid simple relationships with
-# stdio buffer sizes.
-primepat = "1234567890\00\01\02\03\04\05\06"
-
-nullpat = "\0" * 1000
-
-try:
- for size in range(1, 257) + [512, 1000, 1024, 2048, 4096, 8192, 10000,
- 16384, 32768, 65536, 1000000]:
- drive_one(primepat, size)
- drive_one(nullpat, size)
-finally:
- try:
- import os
- os.unlink(TESTFN)
- except:
- pass
+lengths = range(1, 257) + [512, 1000, 1024, 2048, 4096, 8192, 10000,
+ 16384, 32768, 65536, 1000000]
+
+class BufferSizeTest(unittest.TestCase):
+ def try_one(self, s):
+ # Write s + "\n" + s to file, then open it and ensure that successive
+ # .readline()s deliver what we wrote.
+
+ # Since C doesn't guarantee we can write/read arbitrary bytes in text
+ # files, use binary mode.
+ f = open(test_support.TESTFN, "wb")
+ try:
+ # write once with \n and once without
+ f.write(s)
+ f.write("\n")
+ f.write(s)
+ f.close()
+ f = open(test_support.TESTFN, "rb")
+ line = f.readline()
+ self.assertEqual(line, s + "\n")
+ line = f.readline()
+ self.assertEqual(line, s)
+ line = f.readline()
+ self.assert_(not line) # Must be at EOF
+ f.close()
+ finally:
+ try:
+ import os
+ os.unlink(test_support.TESTFN)
+ except:
+ pass
+
+ def drive_one(self, pattern):
+ for length in lengths:
+ # Repeat string 'pattern' as often as needed to reach total length
+ # 'length'. Then call try_one with that string, a string one larger
+ # than that, and a string one smaller than that. Try this with all
+ # small sizes and various powers of 2, so we exercise all likely
+ # stdio buffer sizes, and "off by one" errors on both sides.
+ q, r = divmod(length, len(pattern))
+ teststring = pattern * q + pattern[:r]
+ self.assertEqual(len(teststring), length)
+ self.try_one(teststring)
+ self.try_one(teststring + "x")
+ self.try_one(teststring[:-1])
+
+ def test_primepat(self):
+ # A pattern with prime length, to avoid simple relationships with
+ # stdio buffer sizes.
+ self.drive_one("1234567890\00\01\02\03\04\05\06")
+
+ def test_nullpat(self):
+ self.drive_one("\0" * 1000)
+
+def test_main():
+ test_support.run_unittest(BufferSizeTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 7b245d1..385031f 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -116,6 +116,7 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(abs(0), 0)
self.assertEqual(abs(1234), 1234)
self.assertEqual(abs(-1234), 1234)
+ self.assertTrue(abs(-sys.maxint-1) > 0)
# float
self.assertEqual(abs(0.0), 0.0)
self.assertEqual(abs(3.14), 3.14)
@@ -155,6 +156,11 @@ class BuiltinTest(unittest.TestCase):
S = [10, 20, 30]
self.assertEqual(any(x > 42 for x in S), False)
+ def test_neg(self):
+ x = -sys.maxint-1
+ self.assert_(isinstance(x, int))
+ self.assertEqual(-x, sys.maxint+1)
+
def test_callable(self):
self.assert_(callable(len))
def f(): pass
@@ -686,9 +692,11 @@ class BuiltinTest(unittest.TestCase):
pass
s = repr(-1-sys.maxint)
- self.assertEqual(int(s)+1, -sys.maxint)
+ x = int(s)
+ self.assertEqual(x+1, -sys.maxint)
+ self.assert_(isinstance(x, int))
# should return long
- int(s[1:])
+ self.assertEqual(int(s[1:]), sys.maxint+1)
# should return long
x = int(1e100)
@@ -706,6 +714,11 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(ValueError, int, '123\0')
self.assertRaises(ValueError, int, '53', 40)
+ # SF bug 1545497: embedded NULs were not detected with
+ # explicit base
+ self.assertRaises(ValueError, int, '123\0', 10)
+ self.assertRaises(ValueError, int, '123\x00 245', 20)
+
x = int('1' * 600)
self.assert_(isinstance(x, long))
diff --git a/Lib/test/test_cfgparser.py b/Lib/test/test_cfgparser.py
index 66fecf1..3979f15 100644
--- a/Lib/test/test_cfgparser.py
+++ b/Lib/test/test_cfgparser.py
@@ -1,9 +1,29 @@
import ConfigParser
import StringIO
import unittest
+import UserDict
from test import test_support
+class SortedDict(UserDict.UserDict):
+ def items(self):
+ result = self.data.items()
+ result.sort()
+ return result
+
+ def keys(self):
+ result = self.data.keys()
+ result.sort()
+ return result
+
+ def values(self):
+ result = self.items()
+ return [i[1] for i in values]
+
+ def iteritems(self): return iter(self.items())
+ def iterkeys(self): return iter(self.keys())
+ __iter__ = iterkeys
+ def itervalues(self): return iter(self.values())
class TestCaseBase(unittest.TestCase):
def newconfig(self, defaults=None):
@@ -414,12 +434,36 @@ class SafeConfigParserTestCase(ConfigParserTestCase):
self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
self.assertRaises(TypeError, cf.set, "sect", "option2", object())
+class SortedTestCase(RawConfigParserTestCase):
+ def newconfig(self, defaults=None):
+ self.cf = self.config_class(defaults=defaults, dict_type=SortedDict)
+ return self.cf
+
+ def test_sorted(self):
+ self.fromstring("[b]\n"
+ "o4=1\n"
+ "o3=2\n"
+ "o2=3\n"
+ "o1=4\n"
+ "[a]\n"
+ "k=v\n")
+ output = StringIO.StringIO()
+ self.cf.write(output)
+ self.assertEquals(output.getvalue(),
+ "[a]\n"
+ "k = v\n\n"
+ "[b]\n"
+ "o1 = 4\n"
+ "o2 = 3\n"
+ "o3 = 2\n"
+ "o4 = 1\n\n")
def test_main():
test_support.run_unittest(
ConfigParserTestCase,
RawConfigParserTestCase,
- SafeConfigParserTestCase
+ SafeConfigParserTestCase,
+ SortedTestCase
)
if __name__ == "__main__":
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index f93fa55..52e5e91 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -1,8 +1,9 @@
-from test.test_support import verify, verbose
+from test.test_support import run_unittest
import cgi
import os
import sys
import tempfile
+import unittest
from StringIO import StringIO
class HackedSysModule:
@@ -127,119 +128,124 @@ def first_elts(list):
def first_second_elts(list):
return map(lambda p:(p[0], p[1][0]), list)
-def main():
- for orig, expect in parse_qsl_test_cases:
- result = cgi.parse_qsl(orig, keep_blank_values=True)
- print repr(orig), '=>', result
- verify(result == expect, "Error parsing %s" % repr(orig))
-
- for orig, expect in parse_strict_test_cases:
- # Test basic parsing
- print repr(orig)
- d = do_test(orig, "GET")
- verify(d == expect, "Error parsing %s" % repr(orig))
- d = do_test(orig, "POST")
- verify(d == expect, "Error parsing %s" % repr(orig))
-
- env = {'QUERY_STRING': orig}
- fcd = cgi.FormContentDict(env)
- sd = cgi.SvFormContentDict(env)
- fs = cgi.FieldStorage(environ=env)
- if type(expect) == type({}):
- # test dict interface
- verify(len(expect) == len(fcd))
- verify(norm(expect.keys()) == norm(fcd.keys()))
- verify(norm(expect.values()) == norm(fcd.values()))
- verify(norm(expect.items()) == norm(fcd.items()))
- verify(fcd.get("nonexistent field", "default") == "default")
- verify(len(sd) == len(fs))
- verify(norm(sd.keys()) == norm(fs.keys()))
- verify(fs.getvalue("nonexistent field", "default") == "default")
- # test individual fields
- for key in expect.keys():
- expect_val = expect[key]
- verify(key in fcd)
- verify(norm(fcd[key]) == norm(expect[key]))
- verify(fcd.get(key, "default") == fcd[key])
- verify(key in fs)
- if len(expect_val) > 1:
- single_value = 0
+class CgiTests(unittest.TestCase):
+
+ def test_qsl(self):
+ for orig, expect in parse_qsl_test_cases:
+ result = cgi.parse_qsl(orig, keep_blank_values=True)
+ self.assertEqual(result, expect, "Error parsing %s" % repr(orig))
+
+ def test_strict(self):
+ for orig, expect in parse_strict_test_cases:
+ # Test basic parsing
+ d = do_test(orig, "GET")
+ self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
+ d = do_test(orig, "POST")
+ self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
+
+ env = {'QUERY_STRING': orig}
+ fcd = cgi.FormContentDict(env)
+ sd = cgi.SvFormContentDict(env)
+ fs = cgi.FieldStorage(environ=env)
+ if type(expect) == type({}):
+ # test dict interface
+ self.assertEqual(len(expect), len(fcd))
+ self.assertEqual(norm(expect.keys()), norm(fcd.keys()))
+ self.assertEqual(norm(expect.values()), norm(fcd.values()))
+ self.assertEqual(norm(expect.items()), norm(fcd.items()))
+ self.assertEqual(fcd.get("nonexistent field", "default"), "default")
+ self.assertEqual(len(sd), len(fs))
+ self.assertEqual(norm(sd.keys()), norm(fs.keys()))
+ self.assertEqual(fs.getvalue("nonexistent field", "default"), "default")
+ # test individual fields
+ for key in expect.keys():
+ expect_val = expect[key]
+ self.assert_(key in fcd)
+ self.assertEqual(norm(fcd[key]), norm(expect[key]))
+ self.assertEqual(fcd.get(key, "default"), fcd[key])
+ self.assert_(key in fs)
+ if len(expect_val) > 1:
+ single_value = 0
+ else:
+ single_value = 1
+ try:
+ val = sd[key]
+ except IndexError:
+ self.failIf(single_value)
+ self.assertEqual(fs.getvalue(key), expect_val)
+ else:
+ self.assert_(single_value)
+ self.assertEqual(val, expect_val[0])
+ self.assertEqual(fs.getvalue(key), expect_val[0])
+ self.assertEqual(norm(sd.getlist(key)), norm(expect_val))
+ if single_value:
+ self.assertEqual(norm(sd.values()),
+ first_elts(norm(expect.values())))
+ self.assertEqual(norm(sd.items()),
+ first_second_elts(norm(expect.items())))
+
+ def test_weird_formcontentdict(self):
+ # Test the weird FormContentDict classes
+ env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
+ expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
+ d = cgi.InterpFormContentDict(env)
+ for k, v in expect.items():
+ self.assertEqual(d[k], v)
+ for k, v in d.items():
+ self.assertEqual(expect[k], v)
+ self.assertEqual(norm(expect.values()), norm(d.values()))
+
+ def test_log(self):
+ cgi.log("Testing")
+
+ cgi.logfp = StringIO()
+ cgi.initlog("%s", "Testing initlog 1")
+ cgi.log("%s", "Testing log 2")
+ self.assertEqual(cgi.logfp.getvalue(), "Testing initlog 1\nTesting log 2\n")
+ if os.path.exists("/dev/null"):
+ cgi.logfp = None
+ cgi.logfile = "/dev/null"
+ cgi.initlog("%s", "Testing log 3")
+ cgi.log("Testing log 4")
+
+ def test_fieldstorage_readline(self):
+ # FieldStorage uses readline, which has the capacity to read all
+ # contents of the input file into memory; we use readline's size argument
+ # to prevent that for files that do not contain any newlines in
+ # non-GET/HEAD requests
+ class TestReadlineFile:
+ def __init__(self, file):
+ self.file = file
+ self.numcalls = 0
+
+ def readline(self, size=None):
+ self.numcalls += 1
+ if size:
+ return self.file.readline(size)
else:
- single_value = 1
- try:
- val = sd[key]
- except IndexError:
- verify(not single_value)
- verify(fs.getvalue(key) == expect_val)
- else:
- verify(single_value)
- verify(val == expect_val[0])
- verify(fs.getvalue(key) == expect_val[0])
- verify(norm(sd.getlist(key)) == norm(expect_val))
- if single_value:
- verify(norm(sd.values()) == \
- first_elts(norm(expect.values())))
- verify(norm(sd.items()) == \
- first_second_elts(norm(expect.items())))
-
- # Test the weird FormContentDict classes
- env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
- expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
- d = cgi.InterpFormContentDict(env)
- for k, v in expect.items():
- verify(d[k] == v)
- for k, v in d.items():
- verify(expect[k] == v)
- verify(norm(expect.values()) == norm(d.values()))
-
- print "Testing log"
- cgi.log("Testing")
- cgi.logfp = sys.stdout
- cgi.initlog("%s", "Testing initlog 1")
- cgi.log("%s", "Testing log 2")
- if os.path.exists("/dev/null"):
- cgi.logfp = None
- cgi.logfile = "/dev/null"
- cgi.initlog("%s", "Testing log 3")
- cgi.log("Testing log 4")
-
- print "Test FieldStorage methods that use readline"
- # FieldStorage uses readline, which has the capacity to read all
- # contents of the input file into memory; we use readline's size argument
- # to prevent that for files that do not contain any newlines in
- # non-GET/HEAD requests
- class TestReadlineFile:
- def __init__(self, file):
- self.file = file
- self.numcalls = 0
-
- def readline(self, size=None):
- self.numcalls += 1
- if size:
- return self.file.readline(size)
- else:
- return self.file.readline()
-
- def __getattr__(self, name):
- file = self.__dict__['file']
- a = getattr(file, name)
- if not isinstance(a, int):
- setattr(self, name, a)
- return a
-
- f = TestReadlineFile(tempfile.TemporaryFile())
- f.write('x' * 256 * 1024)
- f.seek(0)
- env = {'REQUEST_METHOD':'PUT'}
- fs = cgi.FieldStorage(fp=f, environ=env)
- # if we're not chunking properly, readline is only called twice
- # (by read_binary); if we are chunking properly, it will be called 5 times
- # as long as the chunksize is 1 << 16.
- verify(f.numcalls > 2)
-
- print "Test basic FieldStorage multipart parsing"
- env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
- postdata = """-----------------------------721837373350705526688164684
+ return self.file.readline()
+
+ def __getattr__(self, name):
+ file = self.__dict__['file']
+ a = getattr(file, name)
+ if not isinstance(a, int):
+ setattr(self, name, a)
+ return a
+
+ f = TestReadlineFile(tempfile.TemporaryFile())
+ f.write('x' * 256 * 1024)
+ f.seek(0)
+ env = {'REQUEST_METHOD':'PUT'}
+ fs = cgi.FieldStorage(fp=f, environ=env)
+ # if we're not chunking properly, readline is only called twice
+ # (by read_binary); if we are chunking properly, it will be called 5 times
+ # as long as the chunksize is 1 << 16.
+ self.assert_(f.numcalls > 2)
+
+ def test_fieldstorage_multipart(self):
+ #Test basic FieldStorage multipart parsing
+ env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
+ postdata = """-----------------------------721837373350705526688164684
Content-Disposition: form-data; name="id"
1234
@@ -259,15 +265,19 @@ Content-Disposition: form-data; name="submit"
Add\x20
-----------------------------721837373350705526688164684--
"""
- fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
- verify(len(fs.list) == 4)
- expect = [{'name':'id', 'filename':None, 'value':'1234'},
- {'name':'title', 'filename':None, 'value':''},
- {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
- {'name':'submit', 'filename':None, 'value':' Add '}]
- for x in range(len(fs.list)):
- for k, exp in expect[x].items():
- got = getattr(fs.list[x], k)
- verify(got == exp)
-
-main()
+ fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
+ self.assertEquals(len(fs.list), 4)
+ expect = [{'name':'id', 'filename':None, 'value':'1234'},
+ {'name':'title', 'filename':None, 'value':''},
+ {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
+ {'name':'submit', 'filename':None, 'value':' Add '}]
+ for x in range(len(fs.list)):
+ for k, exp in expect[x].items():
+ got = getattr(fs.list[x], k)
+ self.assertEquals(got, exp)
+
+def test_main():
+ run_unittest(CgiTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py
index f33462a..3201dd8 100644
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -186,6 +186,14 @@ testme ^ 1
# List/dict operations
+class Empty: pass
+
+try:
+ 1 in Empty()
+ print 'failed, should have raised TypeError'
+except TypeError:
+ pass
+
1 in testme
testme[1]
diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py
index 1bf8583..c558f1b 100644
--- a/Lib/test/test_codecencodings_cn.py
+++ b/Lib/test/test_codecencodings_cn.py
@@ -32,6 +32,7 @@ class Test_GBK(test_multibytecodec_support.TestBase, unittest.TestCase):
("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
("abc\x80\x80\xc1\xc4", "ignore", u"abc\u804a"),
("\x83\x34\x83\x31", "strict", None),
+ (u"\u30fb", "strict", None),
)
class Test_GB18030(test_multibytecodec_support.TestBase, unittest.TestCase):
@@ -45,6 +46,7 @@ class Test_GB18030(test_multibytecodec_support.TestBase, unittest.TestCase):
("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
("abc\x80\x80\xc1\xc4", "ignore", u"abc\u804a"),
("abc\x84\x39\x84\x39\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+ (u"\u30fb", "strict", "\x819\xa79"),
)
has_iso10646 = True
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index 8153979..3c800f8 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -425,6 +425,10 @@ class UTF8SigTest(ReadTest):
]
)
+ def test_bug1601501(self):
+ # SF bug #1601501: check that the codec works with a buffer
+ unicode("\xef\xbb\xbf", "utf-8-sig")
+
class EscapeDecodeTest(unittest.TestCase):
def test_empty(self):
self.assertEquals(codecs.escape_decode(""), ("", 0))
@@ -910,6 +914,18 @@ class StreamReaderTest(unittest.TestCase):
f = self.reader(self.stream)
self.assertEquals(f.readlines(), [u'\ud55c\n', u'\uae00'])
+class EncodedFileTest(unittest.TestCase):
+
+ def test_basic(self):
+ f = StringIO.StringIO('\xed\x95\x9c\n\xea\xb8\x80')
+ ef = codecs.EncodedFile(f, 'utf-16-le', 'utf-8')
+ self.assertEquals(ef.read(), '\\\xd5\n\x00\x00\xae')
+
+ f = StringIO.StringIO()
+ ef = codecs.EncodedFile(f, 'utf-8', 'latin1')
+ ef.write('\xc3\xbc')
+ self.assertEquals(f.getvalue(), '\xfc')
+
class Str2StrTest(unittest.TestCase):
def test_read(self):
@@ -1050,6 +1066,14 @@ broken_unicode_with_streams = [
"punycode",
"unicode_internal"
]
+broken_incremental_coders = broken_unicode_with_streams[:]
+
+# The following encodings only support "strict" mode
+only_strict_mode = [
+ "idna",
+ "zlib_codec",
+ "bz2_codec",
+]
try:
import bz2
@@ -1099,6 +1123,7 @@ class BasicUnicodeTest(unittest.TestCase):
decodedresult += reader.read()
self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+ if encoding not in broken_incremental_coders:
# check incremental decoder/encoder (fetched via the Python
# and C API) and iterencode()/iterdecode()
try:
@@ -1139,6 +1164,24 @@ class BasicUnicodeTest(unittest.TestCase):
result = u"".join(codecs.iterdecode(codecs.iterencode(u"", encoding), encoding))
self.assertEqual(result, u"")
+ if encoding not in only_strict_mode:
+ # check incremental decoder/encoder with errors argument
+ try:
+ encoder = codecs.getincrementalencoder(encoding)("ignore")
+ cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore")
+ except LookupError: # no IncrementalEncoder
+ pass
+ else:
+ encodedresult = "".join(encoder.encode(c) for c in s)
+ decoder = codecs.getincrementaldecoder(encoding)("ignore")
+ decodedresult = u"".join(decoder.decode(c) for c in encodedresult)
+ self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
+ encodedresult = "".join(cencoder.encode(c) for c in s)
+ cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore")
+ decodedresult = u"".join(cdecoder.decode(c) for c in encodedresult)
+ self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
def test_seek(self):
# all codecs should be able to encode these
s = u"%s\n%s\n" % (100*u"abc123", 100*u"def456")
@@ -1214,6 +1257,19 @@ class CharmapTest(unittest.TestCase):
(u"", len(allbytes))
)
+class WithStmtTest(unittest.TestCase):
+ def test_encodedfile(self):
+ f = StringIO.StringIO("\xc3\xbc")
+ with codecs.EncodedFile(f, "latin-1", "utf-8") as ef:
+ self.assertEquals(ef.read(), "\xfc")
+
+ def test_streamreaderwriter(self):
+ f = StringIO.StringIO("\xc3\xbc")
+ info = codecs.lookup("utf-8")
+ with codecs.StreamReaderWriter(f, info.streamreader,
+ info.streamwriter, 'strict') as srw:
+ self.assertEquals(srw.read(), u"\xfc")
+
def test_main():
test_support.run_unittest(
@@ -1234,10 +1290,12 @@ def test_main():
IDNACodecTest,
CodecsModuleTest,
StreamReaderTest,
+ EncodedFileTest,
Str2StrTest,
BasicUnicodeTest,
BasicStrTest,
- CharmapTest
+ CharmapTest,
+ WithStmtTest,
)
diff --git a/Lib/test/test_complex_args.py b/Lib/test/test_complex_args.py
new file mode 100644
index 0000000..c6d50a9
--- /dev/null
+++ b/Lib/test/test_complex_args.py
@@ -0,0 +1,91 @@
+
+import unittest
+from test import test_support
+
+class ComplexArgsTestCase(unittest.TestCase):
+
+ def check(self, func, expected, *args):
+ self.assertEqual(func(*args), expected)
+
+ # These functions are tested below as lambdas too. If you add a function test,
+ # also add a similar lambda test.
+
+ def test_func_parens_no_unpacking(self):
+ def f(((((x))))): return x
+ self.check(f, 1, 1)
+ # Inner parens are elided, same as: f(x,)
+ def f(((x)),): return x
+ self.check(f, 2, 2)
+
+ def test_func_1(self):
+ def f(((((x),)))): return x
+ self.check(f, 3, (3,))
+ def f(((((x)),))): return x
+ self.check(f, 4, (4,))
+ def f(((((x))),)): return x
+ self.check(f, 5, (5,))
+ def f(((x),)): return x
+ self.check(f, 6, (6,))
+
+ def test_func_2(self):
+ def f(((((x)),),)): return x
+ self.check(f, 2, ((2,),))
+
+ def test_func_3(self):
+ def f((((((x)),),),)): return x
+ self.check(f, 3, (((3,),),))
+
+ def test_func_complex(self):
+ def f((((((x)),),),), a, b, c): return x, a, b, c
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ def f(((((((x)),)),),), a, b, c): return x, a, b, c
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ def f(a, b, c, ((((((x)),)),),)): return a, b, c, x
+ self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
+
+ # Duplicate the tests above, but for lambda. If you add a lambda test,
+ # also add a similar function test above.
+
+ def test_lambda_parens_no_unpacking(self):
+ f = lambda (((((x))))): x
+ self.check(f, 1, 1)
+ # Inner parens are elided, same as: f(x,)
+ f = lambda ((x)),: x
+ self.check(f, 2, 2)
+
+ def test_lambda_1(self):
+ f = lambda (((((x),)))): x
+ self.check(f, 3, (3,))
+ f = lambda (((((x)),))): x
+ self.check(f, 4, (4,))
+ f = lambda (((((x))),)): x
+ self.check(f, 5, (5,))
+ f = lambda (((x),)): x
+ self.check(f, 6, (6,))
+
+ def test_lambda_2(self):
+ f = lambda (((((x)),),)): x
+ self.check(f, 2, ((2,),))
+
+ def test_lambda_3(self):
+ f = lambda ((((((x)),),),)): x
+ self.check(f, 3, (((3,),),))
+
+ def test_lambda_complex(self):
+ f = lambda (((((x)),),),), a, b, c: (x, a, b, c)
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ f = lambda ((((((x)),)),),), a, b, c: (x, a, b, c)
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ f = lambda a, b, c, ((((((x)),)),),): (a, b, c, x)
+ self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
+
+
+def test_main():
+ test_support.run_unittest(ComplexArgsTestCase)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py
index 2cf39ae..747785d 100644
--- a/Lib/test/test_contextlib.py
+++ b/Lib/test/test_contextlib.py
@@ -330,32 +330,6 @@ class LockContextTestCase(unittest.TestCase):
return True
self.boilerPlate(lock, locked)
-class DecimalContextTestCase(unittest.TestCase):
-
- # XXX Somebody should write more thorough tests for this
-
- def testBasic(self):
- ctx = decimal.getcontext()
- orig_context = ctx.copy()
- try:
- ctx.prec = save_prec = decimal.ExtendedContext.prec + 5
- with decimal.ExtendedContext.get_manager():
- self.assertEqual(decimal.getcontext().prec,
- decimal.ExtendedContext.prec)
- self.assertEqual(decimal.getcontext().prec, save_prec)
- try:
- with decimal.ExtendedContext.get_manager():
- self.assertEqual(decimal.getcontext().prec,
- decimal.ExtendedContext.prec)
- 1/0
- except ZeroDivisionError:
- self.assertEqual(decimal.getcontext().prec, save_prec)
- else:
- self.fail("Didn't raise ZeroDivisionError")
- finally:
- decimal.setcontext(orig_context)
-
-
# This is needed to make the test actually run under regrtest.py!
def test_main():
run_suite(
diff --git a/Lib/test/test_cookie.py b/Lib/test/test_cookie.py
index c20beee..e7c0cf1 100644
--- a/Lib/test/test_cookie.py
+++ b/Lib/test/test_cookie.py
@@ -1,6 +1,7 @@
# Simple test suite for Cookie.py
-from test.test_support import verify, verbose, run_doctest
+from test.test_support import run_unittest, run_doctest
+import unittest
import Cookie
import warnings
@@ -8,43 +9,74 @@ warnings.filterwarnings("ignore",
".* class is insecure.*",
DeprecationWarning)
-# Currently this only tests SimpleCookie
-
-cases = [
- ('chips=ahoy; vienna=finger', {'chips':'ahoy', 'vienna':'finger'}),
- ('keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
- {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}),
-
- # Check illegal cookies that have an '=' char in an unquoted value
- ('keebler=E=mc2', {'keebler' : 'E=mc2'})
- ]
-
-for data, dict in cases:
- C = Cookie.SimpleCookie() ; C.load(data)
- print repr(C)
- print C.output(sep='\n')
- for k, v in sorted(dict.iteritems()):
- print ' ', k, repr( C[k].value ), repr(v)
- verify(C[k].value == v)
- print C[k]
-
-C = Cookie.SimpleCookie()
-C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
-
-verify(C['Customer'].value == 'WILE_E_COYOTE')
-verify(C['Customer']['version'] == '1')
-verify(C['Customer']['path'] == '/acme')
-
-print C.output(['path'])
-print C.js_output()
-print C.js_output(['path'])
-
-# Try cookie with quoted meta-data
-C = Cookie.SimpleCookie()
-C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
-verify(C['Customer'].value == 'WILE_E_COYOTE')
-verify(C['Customer']['version'] == '1')
-verify(C['Customer']['path'] == '/acme')
-
-print "If anything blows up after this line, it's from Cookie's doctest."
-run_doctest(Cookie)
+class CookieTests(unittest.TestCase):
+ # Currently this only tests SimpleCookie
+ def test_basic(self):
+ cases = [
+ { 'data': 'chips=ahoy; vienna=finger',
+ 'dict': {'chips':'ahoy', 'vienna':'finger'},
+ 'repr': "<SimpleCookie: chips='ahoy' vienna='finger'>",
+ 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger',
+ },
+
+ { 'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
+ 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'},
+ 'repr': '''<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\\n;'>''',
+ 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
+ },
+
+ # Check illegal cookies that have an '=' char in an unquoted value
+ { 'data': 'keebler=E=mc2',
+ 'dict': {'keebler' : 'E=mc2'},
+ 'repr': "<SimpleCookie: keebler='E=mc2'>",
+ 'output': 'Set-Cookie: keebler=E=mc2',
+ }
+ ]
+
+ for case in cases:
+ C = Cookie.SimpleCookie()
+ C.load(case['data'])
+ self.assertEqual(repr(C), case['repr'])
+ self.assertEqual(C.output(sep='\n'), case['output'])
+ for k, v in sorted(case['dict'].iteritems()):
+ self.assertEqual(C[k].value, v)
+
+ def test_load(self):
+ C = Cookie.SimpleCookie()
+ C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
+
+ self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE')
+ self.assertEqual(C['Customer']['version'], '1')
+ self.assertEqual(C['Customer']['path'], '/acme')
+
+ self.assertEqual(C.output(['path']),
+ 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
+ self.assertEqual(C.js_output(), """
+ <script type="text/javascript">
+ <!-- begin hiding
+ document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme; Version=1";
+ // end hiding -->
+ </script>
+ """)
+ self.assertEqual(C.js_output(['path']), """
+ <script type="text/javascript">
+ <!-- begin hiding
+ document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme";
+ // end hiding -->
+ </script>
+ """)
+
+ def test_quoted_meta(self):
+ # Try cookie with quoted meta-data
+ C = Cookie.SimpleCookie()
+ C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
+ self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE')
+ self.assertEqual(C['Customer']['version'], '1')
+ self.assertEqual(C['Customer']['path'], '/acme')
+
+def test_main():
+ run_unittest(CookieTests)
+ run_doctest(Cookie)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index 765bdaf..3329104 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -852,6 +852,7 @@ class TestDate(HarmlessMixedComparison):
t = self.theclass(2005, 3, 2)
self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05")
self.assertEqual(t.strftime(""), "") # SF bug #761337
+ self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784
self.assertRaises(TypeError, t.strftime) # needs an arg
self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 55a53d3..50df93d 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -23,6 +23,7 @@ or Behaviour) to test each part, or without parameter to test both parts. If
you're working through IDLE, you can import this test module and call test_main()
with the corresponding argument.
"""
+from __future__ import with_statement
import unittest
import glob
@@ -1057,6 +1058,32 @@ class ContextAPItests(unittest.TestCase):
self.assertNotEqual(id(c.flags), id(d.flags))
self.assertNotEqual(id(c.traps), id(d.traps))
+class WithStatementTest(unittest.TestCase):
+ # Can't do these as docstrings until Python 2.6
+ # as doctest can't handle __future__ statements
+
+ def test_localcontext(self):
+ # Use a copy of the current context in the block
+ orig_ctx = getcontext()
+ with localcontext() as enter_ctx:
+ set_ctx = getcontext()
+ final_ctx = getcontext()
+ self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
+ self.assert_(orig_ctx is not set_ctx, 'did not copy the context')
+ self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
+
+ def test_localcontextarg(self):
+ # Use a copy of the supplied context in the block
+ orig_ctx = getcontext()
+ new_ctx = Context(prec=42)
+ with localcontext(new_ctx) as enter_ctx:
+ set_ctx = getcontext()
+ final_ctx = getcontext()
+ self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
+ self.assert_(set_ctx.prec == new_ctx.prec, 'did not set correct context')
+ self.assert_(new_ctx is not set_ctx, 'did not copy the context')
+ self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
+
def test_main(arith=False, verbose=None):
""" Execute the tests.
@@ -1077,6 +1104,7 @@ def test_main(arith=False, verbose=None):
DecimalPythonAPItests,
ContextAPItests,
DecimalTest,
+ WithStatementTest,
]
try:
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index d3ae455..2968e3d 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -2017,6 +2017,13 @@ def supers():
veris(Sub.test(), Base.aProp)
+ # Verify that super() doesn't allow keyword args
+ try:
+ super(Base, kw=1)
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "super shouldn't accept keyword args"
def inherits():
if verbose: print "Testing inheritance from basic types..."
@@ -3501,6 +3508,13 @@ def test_mutable_bases():
raise TestFailed, "shouldn't be able to assign to list.__bases__"
try:
+ D.__bases__ = (C2, list)
+ except TypeError:
+ pass
+ else:
+ assert 0, "best_base calculation found wanting"
+
+ try:
del D.__bases__
except TypeError:
pass
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 717ed5e..ff6ccde 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -439,6 +439,16 @@ class DictTest(unittest.TestCase):
else:
self.fail_("g[42] didn't raise KeyError")
+ def test_tuple_keyerror(self):
+ # SF #1576657
+ d = {}
+ try:
+ d[(1,)]
+ except KeyError, e:
+ self.assertEqual(e.args, ((1,),))
+ else:
+ self.fail("missing KeyError")
+
from test import mapping_tests
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index b5c5676..abce41e 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -196,17 +196,21 @@ class ExceptionTests(unittest.TestCase):
test_capi2()
test_capi3()
- def testAttributes(self):
- # test that exception attributes are happy
+ def test_WindowsError(self):
try:
- str(u'Hello \u00E1')
- except Exception, e:
- sampleUnicodeEncodeError = e
+ WindowsError
+ except NameError:
+ pass
+ else:
+ self.failUnlessEqual(str(WindowsError(1001)),
+ "1001")
+ self.failUnlessEqual(str(WindowsError(1001, "message")),
+ "[Error 1001] message")
+ self.failUnlessEqual(WindowsError(1001, "message").errno, 22)
+ self.failUnlessEqual(WindowsError(1001, "message").winerror, 1001)
- try:
- unicode('\xff')
- except Exception, e:
- sampleUnicodeDecodeError = e
+ def testAttributes(self):
+ # test that exception attributes are happy
exceptionList = [
(BaseException, (), {'message' : '', 'args' : ()}),
@@ -218,11 +222,16 @@ class ExceptionTests(unittest.TestCase):
(SystemExit, ('foo',),
{'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
(IOError, ('foo',),
- {'message' : 'foo', 'args' : ('foo',)}),
+ {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
+ 'errno' : None, 'strerror' : None}),
(IOError, ('foo', 'bar'),
- {'message' : '', 'args' : ('foo', 'bar')}),
+ {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
+ 'errno' : 'foo', 'strerror' : 'bar'}),
(IOError, ('foo', 'bar', 'baz'),
- {'message' : '', 'args' : ('foo', 'bar')}),
+ {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
+ 'errno' : 'foo', 'strerror' : 'bar'}),
+ (IOError, ('foo', 'bar', 'baz', 'quux'),
+ {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
(EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
{'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
@@ -249,16 +258,16 @@ class ExceptionTests(unittest.TestCase):
'print_file_and_line' : None, 'msg' : 'msgStr',
'filename' : None, 'lineno' : None, 'offset' : None}),
(UnicodeError, (), {'message' : '', 'args' : (),}),
- (sampleUnicodeEncodeError,
- {'message' : '', 'args' : ('ascii', u'Hello \xe1', 6, 7,
- 'ordinal not in range(128)'),
- 'encoding' : 'ascii', 'object' : u'Hello \xe1',
- 'start' : 6, 'reason' : 'ordinal not in range(128)'}),
- (sampleUnicodeDecodeError,
+ (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
+ {'message' : '', 'args' : ('ascii', u'a', 0, 1,
+ 'ordinal not in range'),
+ 'encoding' : 'ascii', 'object' : u'a',
+ 'start' : 0, 'reason' : 'ordinal not in range'}),
+ (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
{'message' : '', 'args' : ('ascii', '\xff', 0, 1,
- 'ordinal not in range(128)'),
+ 'ordinal not in range'),
'encoding' : 'ascii', 'object' : '\xff',
- 'start' : 0, 'reason' : 'ordinal not in range(128)'}),
+ 'start' : 0, 'reason' : 'ordinal not in range'}),
(UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
{'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
'object' : u'\u3042', 'reason' : 'ouch',
@@ -274,18 +283,14 @@ class ExceptionTests(unittest.TestCase):
except NameError:
pass
- for args in exceptionList:
- expected = args[-1]
+ for exc, args, expected in exceptionList:
try:
- exc = args[0]
- if len(args) == 2:
- raise exc
- else:
- raise exc(*args[1])
+ raise exc(*args)
except BaseException, e:
- if (e is not exc and # needed for sampleUnicode errors
- type(e) is not exc):
+ if type(e) is not exc:
raise
+ # Verify module name
+ self.assertEquals(type(e).__module__, 'exceptions')
# Verify no ref leaks in Exc_str()
s = str(e)
for checkArgName in expected:
@@ -332,6 +337,15 @@ class ExceptionTests(unittest.TestCase):
return -1
self.assertRaises(RuntimeError, g)
+ def testUnicodeStrUsage(self):
+ # Make sure both instances and classes have a str and unicode
+ # representation.
+ self.failUnless(str(Exception))
+ self.failUnless(unicode(Exception))
+ self.failUnless(str(Exception('a')))
+ self.failUnless(unicode(Exception(u'a')))
+
+
def test_main():
run_unittest(ExceptionTests)
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index 58a57b5..2d800b2 100755
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -25,7 +25,7 @@ if sys.platform in ('netbsd1', 'netbsd2', 'netbsd3',
'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
'freebsd6', 'freebsd7',
'bsdos2', 'bsdos3', 'bsdos4',
- 'openbsd', 'openbsd2', 'openbsd3'):
+ 'openbsd', 'openbsd2', 'openbsd3', 'openbsd4'):
if struct.calcsize('l') == 8:
off_t = 'l'
pid_t = 'i'
diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
index a9b3170..8bf5d6e 100644
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -219,8 +219,8 @@ if have_unicode:
test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError,
"unsupported format character '?' (0x3000) at index 5")
-test_exc('%d', '1', TypeError, "int argument required")
-test_exc('%g', '1', TypeError, "float argument required")
+test_exc('%d', '1', TypeError, "int argument required, not str")
+test_exc('%g', '1', TypeError, "float argument required, not str")
test_exc('no format', '1', TypeError,
"not all arguments converted during string formatting")
test_exc('no format', u'1', TypeError,
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 01d6cd2..edc17fc 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -210,6 +210,13 @@ class TestUpdateWrapper(unittest.TestCase):
self.assertEqual(wrapper.attr, 'This is a different test')
self.assertEqual(wrapper.dict_attr, f.dict_attr)
+ def test_builtin_update(self):
+ # Test for bug #1576241
+ def wrapper():
+ pass
+ functools.update_wrapper(wrapper, max)
+ self.assertEqual(wrapper.__name__, 'max')
+ self.assert_(wrapper.__doc__.startswith('max('))
class TestWraps(TestUpdateWrapper):
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py
index f5462e20..9a5f829 100644
--- a/Lib/test/test_future.py
+++ b/Lib/test/test_future.py
@@ -82,6 +82,27 @@ class FutureTest(unittest.TestCase):
else:
self.fail("expected exception didn't occur")
+ def test_parserhack(self):
+ # test that the parser.c::future_hack function works as expected
+ # Note: although this test must pass, it's not testing the original
+ # bug as of 2.6 since the with statement is not optional and
+ # the parser hack disabled. If a new keyword is introduced in
+ # 2.6, change this to refer to the new future import.
+ try:
+ exec("from __future__ import division, with_statement; with = 0")
+ except SyntaxError:
+ pass
+ else:
+ self.fail("syntax error didn't occur")
+
+ try:
+ exec("from __future__ import (with_statement, division); with = 0")
+ except SyntaxError:
+ pass
+ else:
+ self.fail("syntax error didn't occur")
+
+
def test_main():
test_support.run_unittest(FutureTest)
diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py
new file mode 100644
index 0000000..53c4607
--- /dev/null
+++ b/Lib/test/test_genericpath.py
@@ -0,0 +1,184 @@
+import unittest
+from test import test_support
+import os
+import genericpath
+
+class AllCommonTest(unittest.TestCase):
+
+ def assertIs(self, a, b):
+ self.assert_(a is b)
+
+ def test_commonprefix(self):
+ self.assertEqual(
+ genericpath.commonprefix([]),
+ ""
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
+ "/home/swen"
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
+ "/home/swen/"
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]),
+ "/home/swen/spam"
+ )
+
+ def test_getsize(self):
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertEqual(genericpath.getsize(test_support.TESTFN), 3)
+ finally:
+ if not f.closed:
+ f.close()
+ os.remove(test_support.TESTFN)
+
+ def test_time(self):
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ f = open(test_support.TESTFN, "ab")
+ f.write("bar")
+ f.close()
+ f = open(test_support.TESTFN, "rb")
+ d = f.read()
+ f.close()
+ self.assertEqual(d, "foobar")
+
+ self.assert_(
+ genericpath.getctime(test_support.TESTFN) <=
+ genericpath.getmtime(test_support.TESTFN)
+ )
+ finally:
+ if not f.closed:
+ f.close()
+ os.remove(test_support.TESTFN)
+
+ def test_exists(self):
+ self.assertIs(genericpath.exists(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.exists(test_support.TESTFN), True)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.exists)
+
+ def test_isdir(self):
+ self.assertIs(genericpath.isdir(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.isdir(test_support.TESTFN), False)
+ os.remove(test_support.TESTFN)
+ os.mkdir(test_support.TESTFN)
+ self.assertIs(genericpath.isdir(test_support.TESTFN), True)
+ os.rmdir(test_support.TESTFN)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+ try:
+ os.rmdir(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.isdir)
+
+ def test_isfile(self):
+ self.assertIs(genericpath.isfile(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.isfile(test_support.TESTFN), True)
+ os.remove(test_support.TESTFN)
+ os.mkdir(test_support.TESTFN)
+ self.assertIs(genericpath.isfile(test_support.TESTFN), False)
+ os.rmdir(test_support.TESTFN)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+ try:
+ os.rmdir(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.isdir)
+
+ def test_samefile(self):
+ f = open(test_support.TESTFN + "1", "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "1"
+ ),
+ True
+ )
+ # If we don't have links, assume that os.stat doesn't return resonable
+ # inode information and thus, that samefile() doesn't work
+ if hasattr(os, "symlink"):
+ os.symlink(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ )
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ ),
+ True
+ )
+ os.remove(test_support.TESTFN + "2")
+ f = open(test_support.TESTFN + "2", "wb")
+ f.write("bar")
+ f.close()
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ ),
+ False
+ )
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN + "1")
+ except os.error:
+ pass
+ try:
+ os.remove(test_support.TESTFN + "2")
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.samefile)
+
+def test_main():
+ test_support.run_unittest(AllCommonTest)
+
+if __name__=="__main__":
+ test_main()
diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py
index 4cc953c..22e4b25 100644
--- a/Lib/test/test_global.py
+++ b/Lib/test/test_global.py
@@ -1,51 +1,51 @@
"""Verify that warnings are issued for global statements following use."""
-from test.test_support import check_syntax
+from test.test_support import run_unittest, check_syntax_error
+import unittest
import warnings
+warnings.filterwarnings("error", module="<test string>")
-warnings.filterwarnings("error", module="<test code>")
-
-def compile_and_check(text, should_fail=1):
- try:
- compile(text, "<test code>", "exec")
- except SyntaxError, msg:
- if should_fail:
- print "got SyntaxError as expected"
- else:
- print "raised unexpected SyntaxError:", text
- else:
- if should_fail:
- print "should have raised SyntaxError:", text
- else:
- print "as expected, no SyntaxError"
-
-prog_text_1 = """
+class GlobalTests(unittest.TestCase):
+
+ def test1(self):
+ prog_text_1 = """\
def wrong1():
a = 1
b = 2
global a
global b
"""
-compile_and_check(prog_text_1)
+ check_syntax_error(self, prog_text_1)
-prog_text_2 = """
+ def test2(self):
+ prog_text_2 = """\
def wrong2():
print x
global x
"""
-compile_and_check(prog_text_2)
+ check_syntax_error(self, prog_text_2)
-prog_text_3 = """
+ def test3(self):
+ prog_text_3 = """\
def wrong3():
print x
x = 2
global x
"""
-compile_and_check(prog_text_3)
+ check_syntax_error(self, prog_text_3)
-prog_text_4 = """
+ def test4(self):
+ prog_text_4 = """\
global x
x = 2
"""
-compile_and_check(prog_text_4, 0)
+ # this should work
+ compile(prog_text_4, "<test string>", "exec")
+
+
+def test_main():
+ run_unittest(GlobalTests)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index ca84c56..f4a0478 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -8,830 +8,897 @@
# regression test, the filterwarnings() call has been added to
# regrtest.py.
-from test.test_support import TestFailed, verify, vereq, check_syntax
+from test.test_support import run_unittest, check_syntax_error
+import unittest
import sys
+# testing import *
+from sys import *
-print '1. Parser'
-
-print '1.1 Tokens'
-
-print '1.1.1 Backslashes'
-
-# Backslash means line continuation:
-x = 1 \
-+ 1
-if x != 2: raise TestFailed, 'backslash for line continuation'
-
-# Backslash does not means continuation in comments :\
-x = 0
-if x != 0: raise TestFailed, 'backslash ending comment'
-
-print '1.1.2 Numeric literals'
-
-print '1.1.2.1 Plain integers'
-if 0xff != 255: raise TestFailed, 'hex int'
-if 0377 != 255: raise TestFailed, 'octal int'
-if 2147483647 != 017777777777: raise TestFailed, 'large positive int'
-try:
- from sys import maxint
-except ImportError:
- maxint = 2147483647
-if maxint == 2147483647:
- # The following test will start to fail in Python 2.4;
- # change the 020000000000 to -020000000000
- if -2147483647-1 != -020000000000: raise TestFailed, 'max negative int'
- # XXX -2147483648
- if 037777777777 < 0: raise TestFailed, 'large oct'
- if 0xffffffff < 0: raise TestFailed, 'large hex'
- for s in '2147483648', '040000000000', '0x100000000':
- try:
- x = eval(s)
- except OverflowError:
- print "OverflowError on huge integer literal " + repr(s)
-elif eval('maxint == 9223372036854775807'):
- if eval('-9223372036854775807-1 != -01000000000000000000000'):
- raise TestFailed, 'max negative int'
- if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct'
- if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex'
- for s in '9223372036854775808', '02000000000000000000000', \
- '0x10000000000000000':
- try:
- x = eval(s)
- except OverflowError:
- print "OverflowError on huge integer literal " + repr(s)
-else:
- print 'Weird maxint value', maxint
-
-print '1.1.2.2 Long integers'
-x = 0L
-x = 0l
-x = 0xffffffffffffffffL
-x = 0xffffffffffffffffl
-x = 077777777777777777L
-x = 077777777777777777l
-x = 123456789012345678901234567890L
-x = 123456789012345678901234567890l
-
-print '1.1.2.3 Floating point'
-x = 3.14
-x = 314.
-x = 0.314
-# XXX x = 000.314
-x = .314
-x = 3e14
-x = 3E14
-x = 3e-14
-x = 3e+14
-x = 3.e14
-x = .3e14
-x = 3.1e4
-
-print '1.1.3 String literals'
-
-x = ''; y = ""; verify(len(x) == 0 and x == y)
-x = '\''; y = "'"; verify(len(x) == 1 and x == y and ord(x) == 39)
-x = '"'; y = "\""; verify(len(x) == 1 and x == y and ord(x) == 34)
-x = "doesn't \"shrink\" does it"
-y = 'doesn\'t "shrink" does it'
-verify(len(x) == 24 and x == y)
-x = "does \"shrink\" doesn't it"
-y = 'does "shrink" doesn\'t it'
-verify(len(x) == 24 and x == y)
-x = """
+class TokenTests(unittest.TestCase):
+
+ def testBackslash(self):
+ # Backslash means line continuation:
+ x = 1 \
+ + 1
+ self.assertEquals(x, 2, 'backslash for line continuation')
+
+ # Backslash does not means continuation in comments :\
+ x = 0
+ self.assertEquals(x, 0, 'backslash ending comment')
+
+ def testPlainIntegers(self):
+ self.assertEquals(0xff, 255)
+ self.assertEquals(0377, 255)
+ self.assertEquals(2147483647, 017777777777)
+ from sys import maxint
+ if maxint == 2147483647:
+ self.assertEquals(-2147483647-1, -020000000000)
+ # XXX -2147483648
+ self.assert_(037777777777 > 0)
+ self.assert_(0xffffffff > 0)
+ for s in '2147483648', '040000000000', '0x100000000':
+ try:
+ x = eval(s)
+ except OverflowError:
+ self.fail("OverflowError on huge integer literal %r" % s)
+ elif maxint == 9223372036854775807:
+ self.assertEquals(-9223372036854775807-1, -01000000000000000000000)
+ self.assert_(01777777777777777777777 > 0)
+ self.assert_(0xffffffffffffffff > 0)
+ for s in '9223372036854775808', '02000000000000000000000', \
+ '0x10000000000000000':
+ try:
+ x = eval(s)
+ except OverflowError:
+ self.fail("OverflowError on huge integer literal %r" % s)
+ else:
+ self.fail('Weird maxint value %r' % maxint)
+
+ def testLongIntegers(self):
+ x = 0L
+ x = 0l
+ x = 0xffffffffffffffffL
+ x = 0xffffffffffffffffl
+ x = 077777777777777777L
+ x = 077777777777777777l
+ x = 123456789012345678901234567890L
+ x = 123456789012345678901234567890l
+
+ def testFloats(self):
+ x = 3.14
+ x = 314.
+ x = 0.314
+ # XXX x = 000.314
+ x = .314
+ x = 3e14
+ x = 3E14
+ x = 3e-14
+ x = 3e+14
+ x = 3.e14
+ x = .3e14
+ x = 3.1e4
+
+ def testStringLiterals(self):
+ x = ''; y = ""; self.assert_(len(x) == 0 and x == y)
+ x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39)
+ x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34)
+ x = "doesn't \"shrink\" does it"
+ y = 'doesn\'t "shrink" does it'
+ self.assert_(len(x) == 24 and x == y)
+ x = "does \"shrink\" doesn't it"
+ y = 'does "shrink" doesn\'t it'
+ self.assert_(len(x) == 24 and x == y)
+ x = """
The "quick"
brown fox
jumps over
the 'lazy' dog.
"""
-y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
-verify(x == y)
-y = '''
+ y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+ self.assertEquals(x, y)
+ y = '''
The "quick"
brown fox
jumps over
the 'lazy' dog.
-'''; verify(x == y)
-y = "\n\
+'''
+ self.assertEquals(x, y)
+ y = "\n\
The \"quick\"\n\
brown fox\n\
jumps over\n\
the 'lazy' dog.\n\
-"; verify(x == y)
-y = '\n\
+"
+ self.assertEquals(x, y)
+ y = '\n\
The \"quick\"\n\
brown fox\n\
jumps over\n\
the \'lazy\' dog.\n\
-'; verify(x == y)
-
-
-print '1.1.4 Ellipsis literal'
-
-x = ...
-verify(x == Ellipsis)
-
-
-print '1.2 Grammar'
-
-print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE
-# XXX can't test in a script -- this rule is only used when interactive
-
-print 'file_input' # (NEWLINE | stmt)* ENDMARKER
-# Being tested as this very moment this very module
-
-print 'expr_input' # testlist NEWLINE
-# XXX Hard to test -- used only in calls to input()
-
-print 'eval_input' # testlist ENDMARKER
-x = eval('1, 0 or 1')
-
-print 'funcdef'
-### 'def' NAME parameters ':' suite
-### parameters: '(' [varargslist] ')'
-### varargslist: (fpdef ['=' test] ',')*
-### ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
-### | ('**'|'*' '*') NAME)
-### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
-### fpdef: NAME | '(' fplist ')'
-### fplist: fpdef (',' fpdef)* [',']
-### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
-### argument: [test '='] test # Really [keyword '='] test
-def f1(): pass
-f1()
-f1(*())
-f1(*(), **{})
-def f2(one_argument): pass
-def f3(two, arguments): pass
-def f4(two, (compound, (argument, list))): pass
-def f5((compound, first), two): pass
-vereq(f2.func_code.co_varnames, ('one_argument',))
-vereq(f3.func_code.co_varnames, ('two', 'arguments'))
-if sys.platform.startswith('java'):
- vereq(f4.func_code.co_varnames,
- ('two', '(compound, (argument, list))', 'compound', 'argument',
- 'list',))
- vereq(f5.func_code.co_varnames,
- ('(compound, first)', 'two', 'compound', 'first'))
-else:
- vereq(f4.func_code.co_varnames,
- ('two', '.1', 'compound', 'argument', 'list'))
- vereq(f5.func_code.co_varnames,
- ('.0', 'two', 'compound', 'first'))
-def a1(one_arg,): pass
-def a2(two, args,): pass
-def v0(*rest): pass
-def v1(a, *rest): pass
-def v2(a, b, *rest): pass
-def v3(a, (b, c), *rest): return a, b, c, rest
-# ceval unpacks the formal arguments into the first argcount names;
-# thus, the names nested inside tuples must appear after these names.
-if sys.platform.startswith('java'):
- verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c'))
-else:
- vereq(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
-verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,)))
-def d01(a=1): pass
-d01()
-d01(1)
-d01(*(1,))
-d01(**{'a':2})
-def d11(a, b=1): pass
-d11(1)
-d11(1, 2)
-d11(1, **{'b':2})
-def d21(a, b, c=1): pass
-d21(1, 2)
-d21(1, 2, 3)
-d21(*(1, 2, 3))
-d21(1, *(2, 3))
-d21(1, 2, *(3,))
-d21(1, 2, **{'c':3})
-def d02(a=1, b=2): pass
-d02()
-d02(1)
-d02(1, 2)
-d02(*(1, 2))
-d02(1, *(2,))
-d02(1, **{'b':2})
-d02(**{'a': 1, 'b': 2})
-def d12(a, b=1, c=2): pass
-d12(1)
-d12(1, 2)
-d12(1, 2, 3)
-def d22(a, b, c=1, d=2): pass
-d22(1, 2)
-d22(1, 2, 3)
-d22(1, 2, 3, 4)
-def d01v(a=1, *rest): pass
-d01v()
-d01v(1)
-d01v(1, 2)
-d01v(*(1, 2, 3, 4))
-d01v(*(1,))
-d01v(**{'a':2})
-def d11v(a, b=1, *rest): pass
-d11v(1)
-d11v(1, 2)
-d11v(1, 2, 3)
-def d21v(a, b, c=1, *rest): pass
-d21v(1, 2)
-d21v(1, 2, 3)
-d21v(1, 2, 3, 4)
-d21v(*(1, 2, 3, 4))
-d21v(1, 2, **{'c': 3})
-def d02v(a=1, b=2, *rest): pass
-d02v()
-d02v(1)
-d02v(1, 2)
-d02v(1, 2, 3)
-d02v(1, *(2, 3, 4))
-d02v(**{'a': 1, 'b': 2})
-def d12v(a, b=1, c=2, *rest): pass
-d12v(1)
-d12v(1, 2)
-d12v(1, 2, 3)
-d12v(1, 2, 3, 4)
-d12v(*(1, 2, 3, 4))
-d12v(1, 2, *(3, 4, 5))
-d12v(1, *(2,), **{'c': 3})
-def d22v(a, b, c=1, d=2, *rest): pass
-d22v(1, 2)
-d22v(1, 2, 3)
-d22v(1, 2, 3, 4)
-d22v(1, 2, 3, 4, 5)
-d22v(*(1, 2, 3, 4))
-d22v(1, 2, *(3, 4, 5))
-d22v(1, *(2, 3), **{'d': 4})
-def d31v((x)): pass
-d31v(1)
-def d32v((x,)): pass
-d32v((1,))
-#keyword only argument tests
-def pos0key1(*, key): return key
-pos0key1(key=100)
-def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2
-pos2key2(1, 2, k1=100)
-pos2key2(1, 2, k1=100, k2=200)
-pos2key2(1, 2, k2=100, k1=200)
-def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg
-pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
-pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
-
-### lambdef: 'lambda' [varargslist] ':' test
-print 'lambdef'
-l1 = lambda : 0
-verify(l1() == 0)
-l2 = lambda : a[d] # XXX just testing the expression
-l3 = lambda : [2 < x for x in [-1, 3, 0L]]
-verify(l3() == [0, 1, 0])
-l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
-verify(l4() == 1)
-l5 = lambda x, y, z=2: x + y + z
-verify(l5(1, 2) == 5)
-verify(l5(1, 2, 3) == 6)
-check_syntax("lambda x: x = 2")
-l6 = lambda x, y, *, k=20: x+y+k
-verify(l6(1,2) == 1+2+20)
-verify(l6(1,2,k=10) == 1+2+10)
-
-### stmt: simple_stmt | compound_stmt
-# Tested below
-
-### simple_stmt: small_stmt (';' small_stmt)* [';']
-print 'simple_stmt'
-x = 1; pass; del x
-def foo():
- # verify statments that end with semi-colons
- x = 1; pass; del x;
-foo()
-
-### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
-# Tested below
-
-print 'expr_stmt' # (exprlist '=')* exprlist
-1
-1, 2, 3
-x = 1
-x = 1, 2, 3
-x = y = z = 1, 2, 3
-x, y, z = 1, 2, 3
-abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
-# NB these variables are deleted below
-
-check_syntax("x + 1 = 1")
-check_syntax("a + 1 = b + 2")
-
-print 'print_stmt' # 'print' (test ',')* [test]
-print 1, 2, 3
-print 1, 2, 3,
-print
-print 0 or 1, 0 or 1,
-print 0 or 1
-
-print 'extended print_stmt' # 'print' '>>' test ','
-import sys
-print >> sys.stdout, 1, 2, 3
-print >> sys.stdout, 1, 2, 3,
-print >> sys.stdout
-print >> sys.stdout, 0 or 1, 0 or 1,
-print >> sys.stdout, 0 or 1
-
-# test printing to an instance
-class Gulp:
- def write(self, msg): pass
-
-gulp = Gulp()
-print >> gulp, 1, 2, 3
-print >> gulp, 1, 2, 3,
-print >> gulp
-print >> gulp, 0 or 1, 0 or 1,
-print >> gulp, 0 or 1
-
-# test print >> None
-def driver():
- oldstdout = sys.stdout
- sys.stdout = Gulp()
- try:
- tellme(Gulp())
- tellme()
- finally:
- sys.stdout = oldstdout
-
-# we should see this once
-def tellme(file=sys.stdout):
- print >> file, 'hello world'
-
-driver()
-
-# we should not see this at all
-def tellme(file=None):
- print >> file, 'goodbye universe'
-
-driver()
-
-# syntax errors
-check_syntax('print ,')
-check_syntax('print >> x,')
-
-print 'del_stmt' # 'del' exprlist
-del abc
-del x, y, (z, xyz)
-
-print 'pass_stmt' # 'pass'
-pass
-
-print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt
-# Tested below
-
-print 'break_stmt' # 'break'
-while 1: break
-
-print 'continue_stmt' # 'continue'
-i = 1
-while i: i = 0; continue
-
-msg = ""
-while not msg:
- msg = "continue + try/except ok"
- try:
- continue
- msg = "continue failed to continue inside try"
- except:
- msg = "continue inside try called except block"
-print msg
-
-msg = ""
-while not msg:
- msg = "finally block not called"
- try:
- continue
- finally:
- msg = "continue + try/finally ok"
-print msg
-
-
-# This test warrants an explanation. It is a test specifically for SF bugs
-# #463359 and #462937. The bug is that a 'break' statement executed or
-# exception raised inside a try/except inside a loop, *after* a continue
-# statement has been executed in that loop, will cause the wrong number of
-# arguments to be popped off the stack and the instruction pointer reset to
-# a very small number (usually 0.) Because of this, the following test
-# *must* written as a function, and the tracking vars *must* be function
-# arguments with default values. Otherwise, the test will loop and loop.
-
-print "testing continue and break in try/except in loop"
-def test_break_continue_loop(extra_burning_oil = 1, count=0):
- big_hippo = 2
- while big_hippo:
- count += 1
+'
+ self.assertEquals(x, y)
+
+ def testEllipsis(self):
+ x = ...
+ self.assert_(x is Ellipsis)
+
+class GrammarTests(unittest.TestCase):
+
+ # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+ # XXX can't test in a script -- this rule is only used when interactive
+
+ # file_input: (NEWLINE | stmt)* ENDMARKER
+ # Being tested as this very moment this very module
+
+ # expr_input: testlist NEWLINE
+ # XXX Hard to test -- used only in calls to input()
+
+ def testEvalInput(self):
+ # testlist ENDMARKER
+ x = eval('1, 0 or 1')
+
+ def testFuncdef(self):
+ ### 'def' NAME parameters ':' suite
+ ### parameters: '(' [varargslist] ')'
+ ### varargslist: (fpdef ['=' test] ',')*
+ ### ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
+ ### | ('**'|'*' '*') NAME)
+ ### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+ ### fpdef: NAME | '(' fplist ')'
+ ### fplist: fpdef (',' fpdef)* [',']
+ ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
+ ### argument: [test '='] test # Really [keyword '='] test
+ def f1(): pass
+ f1()
+ f1(*())
+ f1(*(), **{})
+ def f2(one_argument): pass
+ def f3(two, arguments): pass
+ def f4(two, (compound, (argument, list))): pass
+ def f5((compound, first), two): pass
+ self.assertEquals(f2.func_code.co_varnames, ('one_argument',))
+ self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments'))
+ if sys.platform.startswith('java'):
+ self.assertEquals(f4.func_code.co_varnames,
+ ('two', '(compound, (argument, list))', 'compound', 'argument',
+ 'list',))
+ self.assertEquals(f5.func_code.co_varnames,
+ ('(compound, first)', 'two', 'compound', 'first'))
+ else:
+ self.assertEquals(f4.func_code.co_varnames,
+ ('two', '.1', 'compound', 'argument', 'list'))
+ self.assertEquals(f5.func_code.co_varnames,
+ ('.0', 'two', 'compound', 'first'))
+ def a1(one_arg,): pass
+ def a2(two, args,): pass
+ def v0(*rest): pass
+ def v1(a, *rest): pass
+ def v2(a, b, *rest): pass
+ def v3(a, (b, c), *rest): return a, b, c, rest
+
+ f1()
+ f2(1)
+ f2(1,)
+ f3(1, 2)
+ f3(1, 2,)
+ f4(1, (2, (3, 4)))
+ v0()
+ v0(1)
+ v0(1,)
+ v0(1,2)
+ v0(1,2,3,4,5,6,7,8,9,0)
+ v1(1)
+ v1(1,)
+ v1(1,2)
+ v1(1,2,3)
+ v1(1,2,3,4,5,6,7,8,9,0)
+ v2(1,2)
+ v2(1,2,3)
+ v2(1,2,3,4)
+ v2(1,2,3,4,5,6,7,8,9,0)
+ v3(1,(2,3))
+ v3(1,(2,3),4)
+ v3(1,(2,3),4,5,6,7,8,9,0)
+
+ # ceval unpacks the formal arguments into the first argcount names;
+ # thus, the names nested inside tuples must appear after these names.
+ if sys.platform.startswith('java'):
+ self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
+ else:
+ self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
+ self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,)))
+ def d01(a=1): pass
+ d01()
+ d01(1)
+ d01(*(1,))
+ d01(**{'a':2})
+ def d11(a, b=1): pass
+ d11(1)
+ d11(1, 2)
+ d11(1, **{'b':2})
+ def d21(a, b, c=1): pass
+ d21(1, 2)
+ d21(1, 2, 3)
+ d21(*(1, 2, 3))
+ d21(1, *(2, 3))
+ d21(1, 2, *(3,))
+ d21(1, 2, **{'c':3})
+ def d02(a=1, b=2): pass
+ d02()
+ d02(1)
+ d02(1, 2)
+ d02(*(1, 2))
+ d02(1, *(2,))
+ d02(1, **{'b':2})
+ d02(**{'a': 1, 'b': 2})
+ def d12(a, b=1, c=2): pass
+ d12(1)
+ d12(1, 2)
+ d12(1, 2, 3)
+ def d22(a, b, c=1, d=2): pass
+ d22(1, 2)
+ d22(1, 2, 3)
+ d22(1, 2, 3, 4)
+ def d01v(a=1, *rest): pass
+ d01v()
+ d01v(1)
+ d01v(1, 2)
+ d01v(*(1, 2, 3, 4))
+ d01v(*(1,))
+ d01v(**{'a':2})
+ def d11v(a, b=1, *rest): pass
+ d11v(1)
+ d11v(1, 2)
+ d11v(1, 2, 3)
+ def d21v(a, b, c=1, *rest): pass
+ d21v(1, 2)
+ d21v(1, 2, 3)
+ d21v(1, 2, 3, 4)
+ d21v(*(1, 2, 3, 4))
+ d21v(1, 2, **{'c': 3})
+ def d02v(a=1, b=2, *rest): pass
+ d02v()
+ d02v(1)
+ d02v(1, 2)
+ d02v(1, 2, 3)
+ d02v(1, *(2, 3, 4))
+ d02v(**{'a': 1, 'b': 2})
+ def d12v(a, b=1, c=2, *rest): pass
+ d12v(1)
+ d12v(1, 2)
+ d12v(1, 2, 3)
+ d12v(1, 2, 3, 4)
+ d12v(*(1, 2, 3, 4))
+ d12v(1, 2, *(3, 4, 5))
+ d12v(1, *(2,), **{'c': 3})
+ def d22v(a, b, c=1, d=2, *rest): pass
+ d22v(1, 2)
+ d22v(1, 2, 3)
+ d22v(1, 2, 3, 4)
+ d22v(1, 2, 3, 4, 5)
+ d22v(*(1, 2, 3, 4))
+ d22v(1, 2, *(3, 4, 5))
+ d22v(1, *(2, 3), **{'d': 4})
+ def d31v((x)): pass
+ d31v(1)
+ def d32v((x,)): pass
+ d32v((1,))
+ # keyword only argument tests
+ def pos0key1(*, key): return key
+ pos0key1(key=100)
+ def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2
+ pos2key2(1, 2, k1=100)
+ pos2key2(1, 2, k1=100, k2=200)
+ pos2key2(1, 2, k2=100, k1=200)
+ def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg
+ pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
+ pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
+
+ def testLambdef(self):
+ ### lambdef: 'lambda' [varargslist] ':' test
+ l1 = lambda : 0
+ self.assertEquals(l1(), 0)
+ l2 = lambda : a[d] # XXX just testing the expression
+ l3 = lambda : [2 < x for x in [-1, 3, 0L]]
+ self.assertEquals(l3(), [0, 1, 0])
+ l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
+ self.assertEquals(l4(), 1)
+ l5 = lambda x, y, z=2: x + y + z
+ self.assertEquals(l5(1, 2), 5)
+ self.assertEquals(l5(1, 2, 3), 6)
+ check_syntax_error(self, "lambda x: x = 2")
+ l6 = lambda x, y, *, k=20: x+y+k
+ self.assertEquals(l6(1,2), 1+2+20)
+ self.assertEquals(l6(1,2,k=10), 1+2+10)
+
+
+ ### stmt: simple_stmt | compound_stmt
+ # Tested below
+
+ def testSimpleStmt(self):
+ ### simple_stmt: small_stmt (';' small_stmt)* [';']
+ x = 1; pass; del x
+ def foo():
+ # verify statments that end with semi-colons
+ x = 1; pass; del x;
+ foo()
+
+ ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt
+ # Tested below
+
+ def testExprStmt(self):
+ # (exprlist '=')* exprlist
+ 1
+ 1, 2, 3
+ x = 1
+ x = 1, 2, 3
+ x = y = z = 1, 2, 3
+ x, y, z = 1, 2, 3
+ abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+
+ check_syntax_error(self, "x + 1 = 1")
+ check_syntax_error(self, "a + 1 = b + 2")
+
+ def testPrintStmt(self):
+ # 'print' (test ',')* [test]
+ import StringIO
+
+ # Can't test printing to real stdout without comparing output
+ # which is not available in unittest.
+ save_stdout = sys.stdout
+ sys.stdout = StringIO.StringIO()
+
+ print 1, 2, 3
+ print 1, 2, 3,
+ print
+ print 0 or 1, 0 or 1,
+ print 0 or 1
+
+ # 'print' '>>' test ','
+ print >> sys.stdout, 1, 2, 3
+ print >> sys.stdout, 1, 2, 3,
+ print >> sys.stdout
+ print >> sys.stdout, 0 or 1, 0 or 1,
+ print >> sys.stdout, 0 or 1
+
+ # test printing to an instance
+ class Gulp:
+ def write(self, msg): pass
+
+ gulp = Gulp()
+ print >> gulp, 1, 2, 3
+ print >> gulp, 1, 2, 3,
+ print >> gulp
+ print >> gulp, 0 or 1, 0 or 1,
+ print >> gulp, 0 or 1
+
+ # test print >> None
+ def driver():
+ oldstdout = sys.stdout
+ sys.stdout = Gulp()
+ try:
+ tellme(Gulp())
+ tellme()
+ finally:
+ sys.stdout = oldstdout
+
+ # we should see this once
+ def tellme(file=sys.stdout):
+ print >> file, 'hello world'
+
+ driver()
+
+ # we should not see this at all
+ def tellme(file=None):
+ print >> file, 'goodbye universe'
+
+ driver()
+
+ self.assertEqual(sys.stdout.getvalue(), '''\
+1 2 3
+1 2 3
+1 1 1
+1 2 3
+1 2 3
+1 1 1
+hello world
+''')
+ sys.stdout = save_stdout
+
+ # syntax errors
+ check_syntax_error(self, 'print ,')
+ check_syntax_error(self, 'print >> x,')
+
+ def testDelStmt(self):
+ # 'del' exprlist
+ abc = [1,2,3]
+ x, y, z = abc
+ xyz = x, y, z
+
+ del abc
+ del x, y, (z, xyz)
+
+ def testPassStmt(self):
+ # 'pass'
+ pass
+
+ # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
+ # Tested below
+
+ def testBreakStmt(self):
+ # 'break'
+ while 1: break
+
+ def testContinueStmt(self):
+ # 'continue'
+ i = 1
+ while i: i = 0; continue
+
+ msg = ""
+ while not msg:
+ msg = "ok"
+ try:
+ continue
+ msg = "continue failed to continue inside try"
+ except:
+ msg = "continue inside try called except block"
+ if msg != "ok":
+ self.fail(msg)
+
+ msg = ""
+ while not msg:
+ msg = "finally block not called"
+ try:
+ continue
+ finally:
+ msg = "ok"
+ if msg != "ok":
+ self.fail(msg)
+
+ def test_break_continue_loop(self):
+ # This test warrants an explanation. It is a test specifically for SF bugs
+ # #463359 and #462937. The bug is that a 'break' statement executed or
+ # exception raised inside a try/except inside a loop, *after* a continue
+ # statement has been executed in that loop, will cause the wrong number of
+ # arguments to be popped off the stack and the instruction pointer reset to
+ # a very small number (usually 0.) Because of this, the following test
+ # *must* written as a function, and the tracking vars *must* be function
+ # arguments with default values. Otherwise, the test will loop and loop.
+
+ def test_inner(extra_burning_oil = 1, count=0):
+ big_hippo = 2
+ while big_hippo:
+ count += 1
+ try:
+ if extra_burning_oil and big_hippo == 1:
+ extra_burning_oil -= 1
+ break
+ big_hippo -= 1
+ continue
+ except:
+ raise
+ if count > 2 or big_hippo != 1:
+ self.fail("continue then break in try/except in loop broken!")
+ test_inner()
+
+ def testReturn(self):
+ # 'return' [testlist]
+ def g1(): return
+ def g2(): return 1
+ g1()
+ x = g2()
+ check_syntax_error(self, "class foo:return 1")
+
+ def testYield(self):
+ check_syntax_error(self, "class foo:yield 1")
+
+ def testRaise(self):
+ # 'raise' test [',' test]
+ try: raise RuntimeError, 'just testing'
+ except RuntimeError: pass
+ try: raise KeyboardInterrupt
+ except KeyboardInterrupt: pass
+
+ def testImport(self):
+ # 'import' dotted_as_names
+ import sys
+ import time, sys
+ # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
+ from time import time
+ from time import (time)
+ # not testable inside a function, but already done at top of the module
+ # from sys import *
+ from sys import path, argv
+ from sys import (path, argv)
+ from sys import (path, argv,)
+
+ def testGlobal(self):
+ # 'global' NAME (',' NAME)*
+ global a
+ global a, b
+ global one, two, three, four, five, six, seven, eight, nine, ten
+
+ def testAssert(self):
+ # assert_stmt: 'assert' test [',' test]
+ assert 1
+ assert 1, 1
+ assert lambda x:x
+ assert 1, lambda x:x+1
try:
- if extra_burning_oil and big_hippo == 1:
- extra_burning_oil -= 1
- break
- big_hippo -= 1
- continue
- except:
- raise
- if count > 2 or big_hippo != 1:
- print "continue then break in try/except in loop broken!"
-test_break_continue_loop()
-
-print 'return_stmt' # 'return' [testlist]
-def g1(): return
-def g2(): return 1
-g1()
-x = g2()
-check_syntax("class foo:return 1")
-
-print 'yield_stmt'
-check_syntax("class foo:yield 1")
-
-print 'raise_stmt' # 'raise' test [',' test]
-try: raise RuntimeError, 'just testing'
-except RuntimeError: pass
-try: raise KeyboardInterrupt
-except KeyboardInterrupt: pass
-
-print 'import_name' # 'import' dotted_as_names
-import sys
-import time, sys
-print 'import_from' # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
-from time import time
-from time import (time)
-from sys import *
-from sys import path, argv
-from sys import (path, argv)
-from sys import (path, argv,)
-
-print 'global_stmt' # 'global' NAME (',' NAME)*
-def f():
- global a
- global a, b
- global one, two, three, four, five, six, seven, eight, nine, ten
-
-print "assert_stmt" # assert_stmt: 'assert' test [',' test]
-assert 1
-assert 1, 1
-assert lambda x:x
-assert 1, lambda x:x+1
-
-### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
-# Tested below
-
-print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
-if 1: pass
-if 1: pass
-else: pass
-if 0: pass
-elif 0: pass
-if 0: pass
-elif 0: pass
-elif 0: pass
-elif 0: pass
-else: pass
-
-print 'while_stmt' # 'while' test ':' suite ['else' ':' suite]
-while 0: pass
-while 0: pass
-else: pass
-
-print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
-for i in 1, 2, 3: pass
-for i, j, k in (): pass
-else: pass
-class Squares:
- def __init__(self, max):
- self.max = max
- self.sofar = []
- def __len__(self): return len(self.sofar)
- def __getitem__(self, i):
- if not 0 <= i < self.max: raise IndexError
- n = len(self.sofar)
- while n <= i:
- self.sofar.append(n*n)
- n = n+1
- return self.sofar[i]
-n = 0
-for x in Squares(10): n = n+x
-if n != 285: raise TestFailed, 'for over growing sequence'
-
-result = []
-for x, in [(1,), (2,), (3,)]:
- result.append(x)
-vereq(result, [1, 2, 3])
-
-print 'try_stmt'
-### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
-### | 'try' ':' suite 'finally' ':' suite
-### except_clause: 'except' [expr [',' expr]]
-try:
- 1/0
-except ZeroDivisionError:
- pass
-else:
- pass
-try: 1/0
-except EOFError: pass
-except TypeError, msg: pass
-except RuntimeError, msg: pass
-except: pass
-else: pass
-try: 1/0
-except (EOFError, TypeError, ZeroDivisionError): pass
-try: 1/0
-except (EOFError, TypeError, ZeroDivisionError), msg: pass
-try: pass
-finally: pass
-
-print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
-if 1: pass
-if 1:
- pass
-if 1:
- #
- #
- #
- pass
- pass
- #
- pass
- #
-
-print 'test'
-### and_test ('or' and_test)*
-### and_test: not_test ('and' not_test)*
-### not_test: 'not' not_test | comparison
-if not 1: pass
-if 1 and 1: pass
-if 1 or 1: pass
-if not not not 1: pass
-if not 1 and 1 and 1: pass
-if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
-
-print 'comparison'
-### comparison: expr (comp_op expr)*
-### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
-if 1: pass
-x = (1 == 1)
-if 1 == 1: pass
-if 1 != 1: pass
-if 1 < 1: pass
-if 1 > 1: pass
-if 1 <= 1: pass
-if 1 >= 1: pass
-if 1 is 1: pass
-if 1 is not 1: pass
-if 1 in (): pass
-if 1 not in (): pass
-if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
-
-print 'binary mask ops'
-x = 1 & 1
-x = 1 ^ 1
-x = 1 | 1
-
-print 'shift ops'
-x = 1 << 1
-x = 1 >> 1
-x = 1 << 1 >> 1
-
-print 'additive ops'
-x = 1
-x = 1 + 1
-x = 1 - 1 - 1
-x = 1 - 1 + 1 - 1 + 1
-
-print 'multiplicative ops'
-x = 1 * 1
-x = 1 / 1
-x = 1 % 1
-x = 1 / 1 * 1 % 1
-
-print 'unary ops'
-x = +1
-x = -1
-x = ~1
-x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
-x = -1*1/1 + 1*1 - ---1*1
-
-print 'selectors'
-### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
-### subscript: expr | [expr] ':' [expr]
-f1()
-f2(1)
-f2(1,)
-f3(1, 2)
-f3(1, 2,)
-f4(1, (2, (3, 4)))
-v0()
-v0(1)
-v0(1,)
-v0(1,2)
-v0(1,2,3,4,5,6,7,8,9,0)
-v1(1)
-v1(1,)
-v1(1,2)
-v1(1,2,3)
-v1(1,2,3,4,5,6,7,8,9,0)
-v2(1,2)
-v2(1,2,3)
-v2(1,2,3,4)
-v2(1,2,3,4,5,6,7,8,9,0)
-v3(1,(2,3))
-v3(1,(2,3),4)
-v3(1,(2,3),4,5,6,7,8,9,0)
-print
-import sys, time
-c = sys.path[0]
-x = time.time()
-x = sys.modules['time'].time()
-a = '01234'
-c = a[0]
-c = a[-1]
-s = a[0:5]
-s = a[:5]
-s = a[0:]
-s = a[:]
-s = a[-5:]
-s = a[:-1]
-s = a[-4:-3]
-# A rough test of SF bug 1333982. http://python.org/sf/1333982
-# The testing here is fairly incomplete.
-# Test cases should include: commas with 1 and 2 colons
-d = {}
-d[1] = 1
-d[1,] = 2
-d[1,2] = 3
-d[1,2,3] = 4
-L = list(d)
-L.sort(key=lambda x: x if isinstance(x, tuple) else ())
-print L
-
-
-print 'atoms'
-### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
-### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
-
-x = (1)
-x = (1 or 2 or 3)
-x = (1 or 2 or 3, 2, 3)
-
-x = []
-x = [1]
-x = [1 or 2 or 3]
-x = [1 or 2 or 3, 2, 3]
-x = []
-
-x = {}
-x = {'one': 1}
-x = {'one': 1,}
-x = {'one' or 'two': 1 or 2}
-x = {'one': 1, 'two': 2}
-x = {'one': 1, 'two': 2,}
-x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
-
-x = {'one'}
-x = {'one', 1,}
-x = {'one', 'two', 'three'}
-x = {2, 3, 4,}
-
-x = x
-x = 'x'
-x = 123
-
-### exprlist: expr (',' expr)* [',']
-### testlist: test (',' test)* [',']
-# These have been exercised enough above
-
-print 'classdef' # 'class' NAME ['(' [testlist] ')'] ':' suite
-class B: pass
-class B2(): pass
-class C1(B): pass
-class C2(B): pass
-class D(C1, C2, B): pass
-class C:
- def meth1(self): pass
- def meth2(self, arg): pass
- def meth3(self, a1, a2): pass
-
-# list comprehension tests
-nums = [1, 2, 3, 4, 5]
-strs = ["Apple", "Banana", "Coconut"]
-spcs = [" Apple", " Banana ", "Coco nut "]
-
-print [s.strip() for s in spcs]
-print [3 * x for x in nums]
-print [x for x in nums if x > 2]
-print [(i, s) for i in nums for s in strs]
-print [(i, s) for i in nums for s in [f for f in strs if "n" in f]]
-print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)]
-
-def test_in_func(l):
- return [0 < x < 3 for x in l if x > 2]
-
-print test_in_func(nums)
-
-def test_nested_front():
- print [[y for y in [x, x + 1]] for x in [1,3,5]]
-
-test_nested_front()
-
-check_syntax("[i, s for i in nums for s in strs]")
-check_syntax("[x if y]")
-
-suppliers = [
- (1, "Boeing"),
- (2, "Ford"),
- (3, "Macdonalds")
-]
-
-parts = [
- (10, "Airliner"),
- (20, "Engine"),
- (30, "Cheeseburger")
-]
-
-suppart = [
- (1, 10), (1, 20), (2, 20), (3, 30)
-]
-
-print [
- (sname, pname)
- for (sno, sname) in suppliers
- for (pno, pname) in parts
- for (sp_sno, sp_pno) in suppart
- if sno == sp_sno and pno == sp_pno
-]
-
-# generator expression tests
-g = ([x for x in range(10)] for x in range(1))
-verify(g.next() == [x for x in range(10)])
-try:
- g.next()
- raise TestFailed, 'should produce StopIteration exception'
-except StopIteration:
- pass
-
-a = 1
-try:
- g = (a for d in a)
- g.next()
- raise TestFailed, 'should produce TypeError'
-except TypeError:
- pass
-
-verify(list((x, y) for x in 'abcd' for y in 'abcd') == [(x, y) for x in 'abcd' for y in 'abcd'])
-verify(list((x, y) for x in 'ab' for y in 'xy') == [(x, y) for x in 'ab' for y in 'xy'])
-
-a = [x for x in range(10)]
-b = (x for x in (y for y in a))
-verify(sum(b) == sum([x for x in range(10)]))
-
-verify(sum(x**2 for x in range(10)) == sum([x**2 for x in range(10)]))
-verify(sum(x*x for x in range(10) if x%2) == sum([x*x for x in range(10) if x%2]))
-verify(sum(x for x in (y for y in range(10))) == sum([x for x in range(10)]))
-verify(sum(x for x in (y for y in (z for z in range(10)))) == sum([x for x in range(10)]))
-verify(sum(x for x in [y for y in (z for z in range(10))]) == sum([x for x in range(10)]))
-verify(sum(x for x in (y for y in (z for z in range(10) if True)) if True) == sum([x for x in range(10)]))
-verify(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True) == 0)
-check_syntax("foo(x for x in range(10), 100)")
-check_syntax("foo(100, x for x in range(10))")
-
-# test for outmost iterable precomputation
-x = 10; g = (i for i in range(x)); x = 5
-verify(len(list(g)) == 10)
-
-# This should hold, since we're only precomputing outmost iterable.
-x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
-x = 5; t = True;
-verify([(i,j) for i in range(10) for j in range(5)] == list(g))
-
-# Grammar allows multiple adjacent 'if's in listcomps and genexps,
-# even though it's silly. Make sure it works (ifelse broke this.)
-verify([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
-verify((x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
-
-# Test ifelse expressions in various cases
-def _checkeval(msg, ret):
- "helper to check that evaluation of expressions is done correctly"
- print x
- return ret
-
-verify([ x() for x in lambda: True, lambda: False if x() ] == [True])
-verify([ x() for x in (lambda: True, lambda: False) if x() ] == [True])
-verify([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ] == [True])
-verify((5 if 1 else _checkeval("check 1", 0)) == 5)
-verify((_checkeval("check 2", 0) if 0 else 5) == 5)
-verify((5 and 6 if 0 else 1) == 1)
-verify(((5 and 6) if 0 else 1) == 1)
-verify((5 and (6 if 1 else 1)) == 6)
-verify((0 or _checkeval("check 3", 2) if 0 else 3) == 3)
-verify((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)) == 1)
-verify((0 or 5 if 1 else _checkeval("check 6", 3)) == 5)
-verify((not 5 if 1 else 1) == False)
-verify((not 5 if 0 else 1) == 1)
-verify((6 + 1 if 1 else 2) == 7)
-verify((6 - 1 if 1 else 2) == 5)
-verify((6 * 2 if 1 else 4) == 12)
-verify((6 / 2 if 1 else 3) == 3)
-verify((6 < 4 if 0 else 2) == 2)
+ assert 0, "msg"
+ except AssertionError, e:
+ self.assertEquals(e.args[0], "msg")
+ else:
+ if __debug__:
+ self.fail("AssertionError not raised by assert 0")
+
+ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+ # Tested below
+
+ def testIf(self):
+ # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+ if 1: pass
+ if 1: pass
+ else: pass
+ if 0: pass
+ elif 0: pass
+ if 0: pass
+ elif 0: pass
+ elif 0: pass
+ elif 0: pass
+ else: pass
+
+ def testWhile(self):
+ # 'while' test ':' suite ['else' ':' suite]
+ while 0: pass
+ while 0: pass
+ else: pass
+
+ def testFor(self):
+ # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+ for i in 1, 2, 3: pass
+ for i, j, k in (): pass
+ else: pass
+ class Squares:
+ def __init__(self, max):
+ self.max = max
+ self.sofar = []
+ def __len__(self): return len(self.sofar)
+ def __getitem__(self, i):
+ if not 0 <= i < self.max: raise IndexError
+ n = len(self.sofar)
+ while n <= i:
+ self.sofar.append(n*n)
+ n = n+1
+ return self.sofar[i]
+ n = 0
+ for x in Squares(10): n = n+x
+ if n != 285:
+ self.fail('for over growing sequence')
+
+ result = []
+ for x, in [(1,), (2,), (3,)]:
+ result.append(x)
+ self.assertEqual(result, [1, 2, 3])
+
+ def testTry(self):
+ ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+ ### | 'try' ':' suite 'finally' ':' suite
+ ### except_clause: 'except' [expr [',' expr]]
+ try:
+ 1/0
+ except ZeroDivisionError:
+ pass
+ else:
+ pass
+ try: 1/0
+ except EOFError: pass
+ except TypeError, msg: pass
+ except RuntimeError, msg: pass
+ except: pass
+ else: pass
+ try: 1/0
+ except (EOFError, TypeError, ZeroDivisionError): pass
+ try: 1/0
+ except (EOFError, TypeError, ZeroDivisionError), msg: pass
+ try: pass
+ finally: pass
+
+ def testSuite(self):
+ # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+ if 1: pass
+ if 1:
+ pass
+ if 1:
+ #
+ #
+ #
+ pass
+ pass
+ #
+ pass
+ #
+
+ def testTest(self):
+ ### and_test ('or' and_test)*
+ ### and_test: not_test ('and' not_test)*
+ ### not_test: 'not' not_test | comparison
+ if not 1: pass
+ if 1 and 1: pass
+ if 1 or 1: pass
+ if not not not 1: pass
+ if not 1 and 1 and 1: pass
+ if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
+
+ def testComparison(self):
+ ### comparison: expr (comp_op expr)*
+ ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+ if 1: pass
+ x = (1 == 1)
+ if 1 == 1: pass
+ if 1 != 1: pass
+ if 1 < 1: pass
+ if 1 > 1: pass
+ if 1 <= 1: pass
+ if 1 >= 1: pass
+ if 1 is 1: pass
+ if 1 is not 1: pass
+ if 1 in (): pass
+ if 1 not in (): pass
+ if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+ def testBinaryMaskOps(self):
+ x = 1 & 1
+ x = 1 ^ 1
+ x = 1 | 1
+
+ def testShiftOps(self):
+ x = 1 << 1
+ x = 1 >> 1
+ x = 1 << 1 >> 1
+
+ def testAdditiveOps(self):
+ x = 1
+ x = 1 + 1
+ x = 1 - 1 - 1
+ x = 1 - 1 + 1 - 1 + 1
+
+ def testMultiplicativeOps(self):
+ x = 1 * 1
+ x = 1 / 1
+ x = 1 % 1
+ x = 1 / 1 * 1 % 1
+
+ def testUnaryOps(self):
+ x = +1
+ x = -1
+ x = ~1
+ x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+ x = -1*1/1 + 1*1 - ---1*1
+
+ def testSelectors(self):
+ ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+ ### subscript: expr | [expr] ':' [expr]
+
+ import sys, time
+ c = sys.path[0]
+ x = time.time()
+ x = sys.modules['time'].time()
+ a = '01234'
+ c = a[0]
+ c = a[-1]
+ s = a[0:5]
+ s = a[:5]
+ s = a[0:]
+ s = a[:]
+ s = a[-5:]
+ s = a[:-1]
+ s = a[-4:-3]
+ # A rough test of SF bug 1333982. http://python.org/sf/1333982
+ # The testing here is fairly incomplete.
+ # Test cases should include: commas with 1 and 2 colons
+ d = {}
+ d[1] = 1
+ d[1,] = 2
+ d[1,2] = 3
+ d[1,2,3] = 4
+ L = list(d)
+ L.sort(key=lambda x: x if isinstance(x, tuple) else ())
+ self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]')
+
+ def testAtoms(self):
+ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
+ ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
+
+ x = (1)
+ x = (1 or 2 or 3)
+ x = (1 or 2 or 3, 2, 3)
+
+ x = []
+ x = [1]
+ x = [1 or 2 or 3]
+ x = [1 or 2 or 3, 2, 3]
+ x = []
+
+ x = {}
+ x = {'one': 1}
+ x = {'one': 1,}
+ x = {'one' or 'two': 1 or 2}
+ x = {'one': 1, 'two': 2}
+ x = {'one': 1, 'two': 2,}
+ x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+
+ x = {'one'}
+ x = {'one', 1,}
+ x = {'one', 'two', 'three'}
+ x = {2, 3, 4,}
+
+ x = x
+ x = 'x'
+ x = 123
+
+ ### exprlist: expr (',' expr)* [',']
+ ### testlist: test (',' test)* [',']
+ # These have been exercised enough above
+
+ def testClassdef(self):
+ # 'class' NAME ['(' [testlist] ')'] ':' suite
+ class B: pass
+ class B2(): pass
+ class C1(B): pass
+ class C2(B): pass
+ class D(C1, C2, B): pass
+ class C:
+ def meth1(self): pass
+ def meth2(self, arg): pass
+ def meth3(self, a1, a2): pass
+
+ def testListcomps(self):
+ # list comprehension tests
+ nums = [1, 2, 3, 4, 5]
+ strs = ["Apple", "Banana", "Coconut"]
+ spcs = [" Apple", " Banana ", "Coco nut "]
+
+ self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut'])
+ self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15])
+ self.assertEqual([x for x in nums if x > 2], [3, 4, 5])
+ self.assertEqual([(i, s) for i in nums for s in strs],
+ [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'),
+ (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'),
+ (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'),
+ (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'),
+ (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')])
+ self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]],
+ [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'),
+ (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'),
+ (5, 'Banana'), (5, 'Coconut')])
+ self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)],
+ [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]])
+
+ def test_in_func(l):
+ return [0 < x < 3 for x in l if x > 2]
+
+ self.assertEqual(test_in_func(nums), [False, False, False])
+
+ def test_nested_front():
+ self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]],
+ [[1, 2], [3, 4], [5, 6]])
+
+ test_nested_front()
+
+ check_syntax_error(self, "[i, s for i in nums for s in strs]")
+ check_syntax_error(self, "[x if y]")
+
+ suppliers = [
+ (1, "Boeing"),
+ (2, "Ford"),
+ (3, "Macdonalds")
+ ]
+
+ parts = [
+ (10, "Airliner"),
+ (20, "Engine"),
+ (30, "Cheeseburger")
+ ]
+
+ suppart = [
+ (1, 10), (1, 20), (2, 20), (3, 30)
+ ]
+
+ x = [
+ (sname, pname)
+ for (sno, sname) in suppliers
+ for (pno, pname) in parts
+ for (sp_sno, sp_pno) in suppart
+ if sno == sp_sno and pno == sp_pno
+ ]
+
+ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'),
+ ('Macdonalds', 'Cheeseburger')])
+
+ def testGenexps(self):
+ # generator expression tests
+ g = ([x for x in range(10)] for x in range(1))
+ self.assertEqual(g.next(), [x for x in range(10)])
+ try:
+ g.next()
+ self.fail('should produce StopIteration exception')
+ except StopIteration:
+ pass
+
+ a = 1
+ try:
+ g = (a for d in a)
+ g.next()
+ self.fail('should produce TypeError')
+ except TypeError:
+ pass
+
+ self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd'])
+ self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy'])
+
+ a = [x for x in range(10)]
+ b = (x for x in (y for y in a))
+ self.assertEqual(sum(b), sum([x for x in range(10)]))
+
+ self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)]))
+ self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2]))
+ self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0)
+ check_syntax_error(self, "foo(x for x in range(10), 100)")
+ check_syntax_error(self, "foo(100, x for x in range(10))")
+
+ def testComprehensionSpecials(self):
+ # test for outmost iterable precomputation
+ x = 10; g = (i for i in range(x)); x = 5
+ self.assertEqual(len(list(g)), 10)
+
+ # This should hold, since we're only precomputing outmost iterable.
+ x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
+ x = 5; t = True;
+ self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g))
+
+ # Grammar allows multiple adjacent 'if's in listcomps and genexps,
+ # even though it's silly. Make sure it works (ifelse broke this.)
+ self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
+ self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
+
+ # verify unpacking single element tuples in listcomp/genexp.
+ self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
+ self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
+
+ def testIfElseExpr(self):
+ # Test ifelse expressions in various cases
+ def _checkeval(msg, ret):
+ "helper to check that evaluation of expressions is done correctly"
+ print x
+ return ret
+
+ self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])
+ self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
+ self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True])
+ self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5)
+ self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5)
+ self.assertEqual((5 and 6 if 0 else 1), 1)
+ self.assertEqual(((5 and 6) if 0 else 1), 1)
+ self.assertEqual((5 and (6 if 1 else 1)), 6)
+ self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3)
+ self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1)
+ self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5)
+ self.assertEqual((not 5 if 1 else 1), False)
+ self.assertEqual((not 5 if 0 else 1), 1)
+ self.assertEqual((6 + 1 if 1 else 2), 7)
+ self.assertEqual((6 - 1 if 1 else 2), 5)
+ self.assertEqual((6 * 2 if 1 else 4), 12)
+ self.assertEqual((6 / 2 if 1 else 3), 3)
+ self.assertEqual((6 < 4 if 0 else 2), 2)
+
+
+def test_main():
+ run_unittest(TokenTests, GrammarTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index 0f8e03e..9989a92 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -128,6 +128,17 @@ class TestGzip(unittest.TestCase):
f.seek(newpos) # positive seek
f.close()
+ def test_seek_whence(self):
+ self.test_write()
+ # Try seek(whence=1), read test
+
+ f = gzip.GzipFile(self.filename)
+ f.read(10)
+ f.seek(10, whence=1)
+ y = f.read(10)
+ f.close()
+ self.assertEquals(y, data1[20:30])
+
def test_seek_write(self):
# Try seek, write test
f = gzip.GzipFile(self.filename, 'w')
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 90bae88..90a4e55 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -10,9 +10,10 @@ class FakeSocket:
def __init__(self, text, fileclass=StringIO.StringIO):
self.text = text
self.fileclass = fileclass
+ self.data = ''
def sendall(self, data):
- self.data = data
+ self.data += data
def makefile(self, mode, bufsize=None):
if mode != 'r' and mode != 'rb':
@@ -70,103 +71,86 @@ class HeaderTests(TestCase):
conn.request('POST', '/', body, headers)
self.assertEqual(conn._buffer.count[header.lower()], 1)
-# Collect output to a buffer so that we don't have to cope with line-ending
-# issues across platforms. Specifically, the headers will have \r\n pairs
-# and some platforms will strip them from the output file.
-
-def test():
- buf = StringIO.StringIO()
- _stdout = sys.stdout
- try:
- sys.stdout = buf
- _test()
- finally:
- sys.stdout = _stdout
-
- # print individual lines with endings stripped
- s = buf.getvalue()
- for line in s.split("\n"):
- print line.strip()
-
-def _test():
- # Test HTTP status lines
-
- body = "HTTP/1.1 200 Ok\r\n\r\nText"
- sock = FakeSocket(body)
- resp = httplib.HTTPResponse(sock, 1)
- resp.begin()
- print resp.read()
- resp.close()
-
- body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
- sock = FakeSocket(body)
- resp = httplib.HTTPResponse(sock, 1)
- try:
+class BasicTest(TestCase):
+ def test_status_lines(self):
+ # Test HTTP status lines
+
+ body = "HTTP/1.1 200 Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = httplib.HTTPResponse(sock)
resp.begin()
- except httplib.BadStatusLine:
- print "BadStatusLine raised as expected"
- else:
- print "Expect BadStatusLine"
-
- # Check invalid host_port
-
- for hp in ("www.python.org:abc", "www.python.org:"):
- try:
- h = httplib.HTTP(hp)
- except httplib.InvalidURL:
- print "InvalidURL raised as expected"
- else:
- print "Expect InvalidURL"
-
- for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
- ("www.python.org:80", "www.python.org", 80),
- ("www.python.org", "www.python.org", 80),
- ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
- try:
+ self.assertEqual(resp.read(), 'Text')
+ resp.close()
+
+ body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = httplib.HTTPResponse(sock)
+ self.assertRaises(httplib.BadStatusLine, resp.begin)
+
+ def test_host_port(self):
+ # Check invalid host_port
+
+ for hp in ("www.python.org:abc", "www.python.org:"):
+ self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
+
+ for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
+ ("www.python.org:80", "www.python.org", 80),
+ ("www.python.org", "www.python.org", 80),
+ ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
http = httplib.HTTP(hp)
- except httplib.InvalidURL:
- print "InvalidURL raised erroneously"
- c = http._conn
- if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host)
- if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host)
-
- # test response with multiple message headers with the same field name.
- text = ('HTTP/1.1 200 OK\r\n'
- 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
- 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
- ' Path="/acme"\r\n'
- '\r\n'
- 'No body\r\n')
- hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
- ', '
- 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
- s = FakeSocket(text)
- r = httplib.HTTPResponse(s, 1)
- r.begin()
- cookies = r.getheader("Set-Cookie")
- if cookies != hdr:
- raise AssertionError, "multiple headers not combined properly"
-
- # Test that the library doesn't attempt to read any data
- # from a HEAD request. (Tickles SF bug #622042.)
- sock = FakeSocket(
- 'HTTP/1.1 200 OK\r\n'
- 'Content-Length: 14432\r\n'
- '\r\n',
- NoEOFStringIO)
- resp = httplib.HTTPResponse(sock, 1, method="HEAD")
- resp.begin()
- if resp.read() != "":
- raise AssertionError, "Did not expect response from HEAD request"
- resp.close()
+ c = http._conn
+ if h != c.host: self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
+ if p != c.port: self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
+
+ def test_response_headers(self):
+ # test response with multiple message headers with the same field name.
+ text = ('HTTP/1.1 200 OK\r\n'
+ 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
+ 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
+ ' Path="/acme"\r\n'
+ '\r\n'
+ 'No body\r\n')
+ hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
+ ', '
+ 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
+ s = FakeSocket(text)
+ r = httplib.HTTPResponse(s)
+ r.begin()
+ cookies = r.getheader("Set-Cookie")
+ if cookies != hdr:
+ self.fail("multiple headers not combined properly")
+
+ def test_read_head(self):
+ # Test that the library doesn't attempt to read any data
+ # from a HEAD request. (Tickles SF bug #622042.)
+ sock = FakeSocket(
+ 'HTTP/1.1 200 OK\r\n'
+ 'Content-Length: 14432\r\n'
+ '\r\n',
+ NoEOFStringIO)
+ resp = httplib.HTTPResponse(sock, method="HEAD")
+ resp.begin()
+ if resp.read() != "":
+ self.fail("Did not expect response from HEAD request")
+ resp.close()
+
+ def test_send_file(self):
+ expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
+ 'Accept-Encoding: identity\r\nContent-Length:'
+ body = open(__file__, 'rb')
+ conn = httplib.HTTPConnection('example.com')
+ sock = FakeSocket(body)
+ conn.sock = sock
+ conn.request('GET', '/foo', body)
+ self.assertTrue(sock.data.startswith(expected))
class OfflineTest(TestCase):
def test_responses(self):
self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
def test_main(verbose=None):
- tests = [HeaderTests,OfflineTest]
- test_support.run_unittest(*tests)
+ test_support.run_unittest(HeaderTests, OfflineTest, BasicTest)
-test()
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py
index 893ba24..62b14e0 100644
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -1,43 +1,47 @@
import imp
-from test.test_support import TestFailed, TestSkipped
-try:
- import thread
-except ImportError:
- raise TestSkipped("test only valid when thread support is available")
+import thread
+import unittest
+from test import test_support
-def verify_lock_state(expected):
- if imp.lock_held() != expected:
- raise TestFailed("expected imp.lock_held() to be %r" % expected)
-def testLock():
- LOOPS = 50
+class LockTests(unittest.TestCase):
- # The import lock may already be held, e.g. if the test suite is run
- # via "import test.autotest".
- lock_held_at_start = imp.lock_held()
- verify_lock_state(lock_held_at_start)
+ """Very basic test of import lock functions."""
- for i in range(LOOPS):
- imp.acquire_lock()
- verify_lock_state(True)
+ def verify_lock_state(self, expected):
+ self.failUnlessEqual(imp.lock_held(), expected,
+ "expected imp.lock_held() to be %r" % expected)
+ def testLock(self):
+ LOOPS = 50
- for i in range(LOOPS):
- imp.release_lock()
+ # The import lock may already be held, e.g. if the test suite is run
+ # via "import test.autotest".
+ lock_held_at_start = imp.lock_held()
+ self.verify_lock_state(lock_held_at_start)
- # The original state should be restored now.
- verify_lock_state(lock_held_at_start)
+ for i in range(LOOPS):
+ imp.acquire_lock()
+ self.verify_lock_state(True)
- if not lock_held_at_start:
- try:
+ for i in range(LOOPS):
imp.release_lock()
- except RuntimeError:
- pass
- else:
- raise TestFailed("release_lock() without lock should raise "
- "RuntimeError")
+
+ # The original state should be restored now.
+ self.verify_lock_state(lock_held_at_start)
+
+ if not lock_held_at_start:
+ try:
+ imp.release_lock()
+ except RuntimeError:
+ pass
+ else:
+ self.fail("release_lock() without lock should raise "
+ "RuntimeError")
def test_main():
- testLock()
+ test_support.run_unittest(
+ LockTests,
+ )
if __name__ == "__main__":
test_main()
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index b64c23b..e37378f 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -1,21 +1,11 @@
-from test.test_support import TESTFN, TestFailed
+from test.test_support import TESTFN, run_unittest
+import unittest
import os
import random
import sys
import py_compile
-# Brief digression to test that import is case-sensitive: if we got this
-# far, we know for sure that "random" exists.
-try:
- import RAnDoM
-except ImportError:
- pass
-else:
- raise TestFailed("import of RAnDoM should have failed (case mismatch)")
-
-# Another brief digression to test the accuracy of manifest float constants.
-from test import double_const # don't blink -- that *was* the test
def remove_files(name):
for f in (name + os.extsep + "py",
@@ -26,199 +16,206 @@ def remove_files(name):
if os.path.exists(f):
os.remove(f)
-def test_with_extension(ext): # ext normally ".py"; perhaps ".pyw"
- source = TESTFN + ext
- pyo = TESTFN + os.extsep + "pyo"
- if sys.platform.startswith('java'):
- pyc = TESTFN + "$py.class"
- else:
- pyc = TESTFN + os.extsep + "pyc"
-
- f = open(source, "w")
- print >> f, "# This tests Python's ability to import a", ext, "file."
- a = random.randrange(1000)
- b = random.randrange(1000)
- print >> f, "a =", a
- print >> f, "b =", b
- f.close()
-
- try:
- try:
- mod = __import__(TESTFN)
- except ImportError, err:
- raise ValueError("import from %s failed: %s" % (ext, err))
- if mod.a != a or mod.b != b:
- print a, "!=", mod.a
- print b, "!=", mod.b
- raise ValueError("module loaded (%s) but contents invalid" % mod)
- finally:
- os.unlink(source)
+class ImportTest(unittest.TestCase):
- try:
- try:
- reload(mod)
- except ImportError, err:
- raise ValueError("import from .pyc/.pyo failed: %s" % err)
- finally:
+ def testCaseSensitivity(self):
+ # Brief digression to test that import is case-sensitive: if we got this
+ # far, we know for sure that "random" exists.
try:
- os.unlink(pyc)
- except os.error:
+ import RAnDoM
+ except ImportError:
pass
- try:
- os.unlink(pyo)
- except os.error:
- pass
- del sys.modules[TESTFN]
-
-sys.path.insert(0, os.curdir)
-try:
- test_with_extension(os.extsep + "py")
- if sys.platform.startswith("win"):
- for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
- test_with_extension(ext)
-finally:
- del sys.path[0]
-
-# Verify that the imp module can correctly load and find .py files
-import imp
-x = imp.find_module("os")
-os = imp.load_module("os", *x)
-
-def test_module_with_large_stack(module):
- # create module w/list of 65000 elements to test bug #561858
- filename = module + os.extsep + 'py'
-
- # create a file with a list of 65000 elements
- f = open(filename, 'w+')
- f.write('d = [\n')
- for i in range(65000):
- f.write('"",\n')
- f.write(']')
- f.close()
-
- # compile & remove .py file, we only need .pyc (or .pyo)
- f = open(filename, 'r')
- py_compile.compile(filename)
- f.close()
- os.unlink(filename)
-
- # need to be able to load from current dir
- sys.path.append('')
-
- # this used to crash
- exec('import ' + module)
-
- # cleanup
- del sys.path[-1]
- for ext in 'pyc', 'pyo':
- fname = module + os.extsep + ext
- if os.path.exists(fname):
- os.unlink(fname)
-
-test_module_with_large_stack('longlist')
-
-def test_failing_import_sticks():
- source = TESTFN + os.extsep + "py"
- f = open(source, "w")
- print >> f, "a = 1/0"
- f.close()
-
- # New in 2.4, we shouldn't be able to import that no matter how often
- # we try.
- sys.path.insert(0, os.curdir)
- try:
- for i in 1, 2, 3:
- try:
- mod = __import__(TESTFN)
- except ZeroDivisionError:
- if TESTFN in sys.modules:
- raise TestFailed("damaged module in sys.modules", i)
+ else:
+ self.fail("import of RAnDoM should have failed (case mismatch)")
+
+ def testDoubleConst(self):
+ # Another brief digression to test the accuracy of manifest float constants.
+ from test import double_const # don't blink -- that *was* the test
+
+ def testImport(self):
+ def test_with_extension(ext):
+ # ext normally ".py"; perhaps ".pyw"
+ source = TESTFN + ext
+ pyo = TESTFN + os.extsep + "pyo"
+ if sys.platform.startswith('java'):
+ pyc = TESTFN + "$py.class"
else:
- raise TestFailed("was able to import a damaged module", i)
- finally:
- sys.path.pop(0)
- remove_files(TESTFN)
-
-test_failing_import_sticks()
-
-def test_failing_reload():
- # A failing reload should leave the module object in sys.modules.
- source = TESTFN + os.extsep + "py"
- f = open(source, "w")
- print >> f, "a = 1"
- print >> f, "b = 2"
- f.close()
-
- sys.path.insert(0, os.curdir)
- try:
- mod = __import__(TESTFN)
- if TESTFN not in sys.modules:
- raise TestFailed("expected module in sys.modules")
- if mod.a != 1 or mod.b != 2:
- raise TestFailed("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.
+ pyc = TESTFN + os.extsep + "pyc"
+
+ f = open(source, "w")
+ print >> f, "# This tests Python's ability to import a", ext, "file."
+ a = random.randrange(1000)
+ b = random.randrange(1000)
+ print >> f, "a =", a
+ print >> f, "b =", b
+ f.close()
+
+ try:
+ try:
+ mod = __import__(TESTFN)
+ except ImportError, err:
+ self.fail("import from %s failed: %s" % (ext, err))
+
+ self.assertEquals(mod.a, a,
+ "module loaded (%s) but contents invalid" % mod)
+ self.assertEquals(mod.b, b,
+ "module loaded (%s) but contents invalid" % mod)
+ finally:
+ os.unlink(source)
+
+ try:
+ try:
+ reload(mod)
+ except ImportError, 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
+ del sys.modules[TESTFN]
+
+ sys.path.insert(0, os.curdir)
+ try:
+ test_with_extension(os.extsep + "py")
+ if sys.platform.startswith("win"):
+ for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
+ test_with_extension(ext)
+ finally:
+ del sys.path[0]
+
+ def testImpModule(self):
+ # Verify that the imp module can correctly load and find .py files
+ import imp
+ x = imp.find_module("os")
+ os = imp.load_module("os", *x)
+
+ def test_module_with_large_stack(self, module='longlist'):
+ # create module w/list of 65000 elements to test bug #561858
+ filename = module + os.extsep + 'py'
+
+ # create a file with a list of 65000 elements
+ f = open(filename, 'w+')
+ f.write('d = [\n')
+ for i in range(65000):
+ f.write('"",\n')
+ f.write(']')
+ f.close()
+
+ # compile & remove .py file, we only need .pyc (or .pyo)
+ f = open(filename, 'r')
+ py_compile.compile(filename)
+ f.close()
+ os.unlink(filename)
+
+ # need to be able to load from current dir
+ sys.path.append('')
+
+ # this used to crash
+ exec('import ' + module)
+
+ # cleanup
+ del sys.path[-1]
+ for ext in 'pyc', 'pyo':
+ fname = module + os.extsep + ext
+ if os.path.exists(fname):
+ os.unlink(fname)
+
+ def test_failing_import_sticks(self):
+ source = TESTFN + os.extsep + "py"
f = open(source, "w")
- print >> f, "a = 10"
- print >> f, "b = 20//0"
+ print >> f, "a = 1/0"
f.close()
+
+ # New in 2.4, we shouldn't be able to import that no matter how often
+ # we try.
+ sys.path.insert(0, os.curdir)
try:
- reload(mod)
- except ZeroDivisionError:
- pass
- else:
- raise TestFailed("was able to reload a damaged module")
-
- # But we still expect the module to be in sys.modules.
- mod = sys.modules.get(TESTFN)
- if mod is None:
- raise TestFailed("expected module to still be in sys.modules")
- # We should have replaced a w/ 10, but the old b value should
- # stick.
- if mod.a != 10 or mod.b != 2:
- raise TestFailed("module has wrong attribute values")
-
- finally:
- sys.path.pop(0)
- remove_files(TESTFN)
- if TESTFN in sys.modules:
- del sys.modules[TESTFN]
-
-test_failing_reload()
-
-def test_import_name_binding():
- # import x.y.z binds x in the current namespace
- import test as x
- import test.test_support
- assert x is test, x.__name__
- assert hasattr(test.test_support, "__file__")
-
- # import x.y.z as w binds z as w
- import test.test_support as y
- assert y is test.test_support, y.__name__
-
-test_import_name_binding()
-
-def test_import_initless_directory_warning():
- import warnings
- oldfilters = warnings.filters[:]
- warnings.simplefilter('error', ImportWarning);
- try:
- # Just a random non-package directory we always expect to be
- # somewhere in sys.path...
- __import__("site-packages")
- except ImportWarning:
- pass
- else:
- raise AssertionError
- finally:
- warnings.filters = oldfilters
-
-test_import_initless_directory_warning()
+ for i in 1, 2, 3:
+ try:
+ mod = __import__(TESTFN)
+ except ZeroDivisionError:
+ if TESTFN in sys.modules:
+ self.fail("damaged module in sys.modules on %i. try" % i)
+ else:
+ self.fail("was able to import a damaged module on %i. try" % i)
+ finally:
+ 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 >> f, "a = 1"
+ print >> f, "b = 2"
+ 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 >> f, "a = 10"
+ print >> f, "b = 20//0"
+ 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_import_name_binding(self):
+ # import x.y.z binds x in the current namespace
+ import test as x
+ import test.test_support
+ self.assert_(x is test, x.__name__)
+ self.assert_(hasattr(test.test_support, "__file__"))
+
+ # import x.y.z as w binds z as w
+ import test.test_support as y
+ self.assert_(y is test.test_support, y.__name__)
+
+ def test_import_initless_directory_warning(self):
+ import warnings
+ oldfilters = warnings.filters[:]
+ warnings.simplefilter('error', ImportWarning);
+ try:
+ # Just a random non-package directory we always expect to be
+ # somewhere in sys.path...
+ self.assertRaises(ImportWarning, __import__, "site-packages")
+ finally:
+ warnings.filters = oldfilters
+
+def test_main(verbose=None):
+ run_unittest(ImportTest)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index e5946e9..071e521 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -180,7 +180,18 @@ class TestRetrievingSourceCode(GetSourceBase):
self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
def test_getmodule(self):
+ # Check actual module
+ self.assertEqual(inspect.getmodule(mod), mod)
+ # Check class (uses __module__ attribute)
self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
+ # Check a method (no __module__ attribute, falls back to filename)
+ self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
+ # Do it again (check the caching isn't broken)
+ self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
+ # Check a builtin
+ self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
+ # Check filename override
+ self.assertEqual(inspect.getmodule(None, modfile), mod)
def test_getsource(self):
self.assertSourceEqual(git.abuse, 29, 39)
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index 8f8fc73..8e1118a 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -61,6 +61,10 @@ class TestBasicOps(unittest.TestCase):
self.assertEqual(repr(c), 'count(3)')
c.next()
self.assertEqual(repr(c), 'count(4)')
+ c = count(-9)
+ self.assertEqual(repr(c), 'count(-9)')
+ c.next()
+ self.assertEqual(c.next(), -8)
def test_cycle(self):
self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))
@@ -375,6 +379,7 @@ class TestBasicOps(unittest.TestCase):
# test values of n
self.assertRaises(TypeError, tee, 'abc', 'invalid')
+ self.assertRaises(ValueError, tee, [], -1)
for n in xrange(5):
result = tee('abc', n)
self.assertEqual(type(result), tuple)
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index 92fe7a1..e0c781f 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -247,17 +247,23 @@ class LongTest(unittest.TestCase):
"long(-sys.maxint-1) != -sys.maxint-1")
# long -> int should not fail for hugepos_aslong or hugeneg_aslong
+ x = int(hugepos_aslong)
try:
- self.assertEqual(int(hugepos_aslong), hugepos,
+ self.assertEqual(x, hugepos,
"converting sys.maxint to long and back to int fails")
except OverflowError:
self.fail("int(long(sys.maxint)) overflowed!")
+ if not isinstance(x, int):
+ raise TestFailed("int(long(sys.maxint)) should have returned int")
+ x = int(hugeneg_aslong)
try:
- self.assertEqual(int(hugeneg_aslong), hugeneg,
+ self.assertEqual(x, hugeneg,
"converting -sys.maxint-1 to long and back to int fails")
except OverflowError:
self.fail("int(long(-sys.maxint-1)) overflowed!")
-
+ if not isinstance(x, int):
+ raise TestFailed("int(long(-sys.maxint-1)) should have "
+ "returned int")
# but long -> int should overflow for hugepos+1 and hugeneg-1
x = hugepos_aslong + 1
try:
@@ -282,6 +288,17 @@ class LongTest(unittest.TestCase):
self.assert_(type(y) is long,
"overflowing int conversion must return long not long subtype")
+ # long -> Py_ssize_t conversion
+ class X(object):
+ def __getslice__(self, i, j):
+ return i, j
+
+ self.assertEqual(X()[-5L:7L], (-5, 7))
+ # use the clamping effect to test the smallest and largest longs
+ # that fit a Py_ssize_t
+ slicemin, slicemax = X()[-2L**100:2L**100]
+ self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
+
# ----------------------------------- tests of auto int->long conversion
def test_auto_overflow(self):
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index 1837306..def58cc 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -666,6 +666,19 @@ class TestMaildir(TestMailbox):
self._box.lock()
self._box.unlock()
+ def test_folder (self):
+ # Test for bug #1569790: verify that folders returned by .get_folder()
+ # use the same factory function.
+ def dummy_factory (s):
+ return None
+ box = self._factory(self._path, factory=dummy_factory)
+ folder = box.add_folder('folder1')
+ self.assert_(folder._factory is dummy_factory)
+
+ folder1_alias = box.get_folder('folder1')
+ self.assert_(folder1_alias._factory is dummy_factory)
+
+
class _TestMboxMMDF(TestMailbox):
@@ -740,6 +753,22 @@ class _TestMboxMMDF(TestMailbox):
self._box.lock()
self._box.unlock()
+ def test_relock(self):
+ # Test case for bug #1575506: the mailbox class was locking the
+ # wrong file object in its flush() method.
+ msg = "Subject: sub\n\nbody\n"
+ key1 = self._box.add(msg)
+ self._box.flush()
+ self._box.close()
+
+ self._box = self._factory(self._path)
+ self._box.lock()
+ key2 = self._box.add(msg)
+ self._box.flush()
+ self.assert_(self._box._locked)
+ self._box.close()
+
+
class TestMbox(_TestMboxMMDF):
@@ -766,7 +795,11 @@ class TestMH(TestMailbox):
def test_get_folder(self):
# Open folders
- self._box.add_folder('foo.bar')
+ def dummy_factory (s):
+ return None
+ self._box = self._factory(self._path, dummy_factory)
+
+ new_folder = self._box.add_folder('foo.bar')
folder0 = self._box.get_folder('foo.bar')
folder0.add(self._template % 'bar')
self.assert_(os.path.isdir(os.path.join(self._path, 'foo.bar')))
@@ -774,6 +807,11 @@ class TestMH(TestMailbox):
self.assert_(folder1.get_string(folder1.keys()[0]) == \
self._template % 'bar')
+ # Test for bug #1569790: verify that folders returned by .get_folder()
+ # use the same factory function.
+ self.assert_(new_folder._factory is self._box._factory)
+ self.assert_(folder0._factory is self._box._factory)
+
def test_add_and_remove_folders(self):
# Delete folders
self._box.add_folder('one')
@@ -842,6 +880,21 @@ class TestMH(TestMailbox):
self.assert_(self._box.get_sequences() ==
{'foo':[1, 2, 3], 'unseen':[1], 'bar':[3], 'replied':[3]})
+ # Test case for packing while holding the mailbox locked.
+ key0 = self._box.add(msg1)
+ key1 = self._box.add(msg1)
+ key2 = self._box.add(msg1)
+ key3 = self._box.add(msg1)
+
+ self._box.remove(key0)
+ self._box.remove(key2)
+ self._box.lock()
+ self._box.pack()
+ self._box.unlock()
+ self.assert_(self._box.get_sequences() ==
+ {'foo':[1, 2, 3, 4, 5],
+ 'unseen':[1], 'bar':[3], 'replied':[3]})
+
def _get_lock_path(self):
return os.path.join(self._path, '.mh_sequences.lock')
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index a092265..a45fc34 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -1,208 +1,241 @@
# Python test set -- math module
# XXXX Should not do tests around zero only
-from test.test_support import TestFailed, verbose
+from test.test_support import run_unittest, verbose
+import unittest
+import math
seps='1e-05'
eps = eval(seps)
-print 'math module, testing with eps', seps
-import math
-def testit(name, value, expected):
- if abs(value-expected) > eps:
- raise TestFailed, '%s returned %f, expected %f'%\
- (name, value, expected)
-
-print 'constants'
-testit('pi', math.pi, 3.1415926)
-testit('e', math.e, 2.7182818)
-
-print 'acos'
-testit('acos(-1)', math.acos(-1), math.pi)
-testit('acos(0)', math.acos(0), math.pi/2)
-testit('acos(1)', math.acos(1), 0)
-
-print 'asin'
-testit('asin(-1)', math.asin(-1), -math.pi/2)
-testit('asin(0)', math.asin(0), 0)
-testit('asin(1)', math.asin(1), math.pi/2)
-
-print 'atan'
-testit('atan(-1)', math.atan(-1), -math.pi/4)
-testit('atan(0)', math.atan(0), 0)
-testit('atan(1)', math.atan(1), math.pi/4)
-
-print 'atan2'
-testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
-testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
-testit('atan2(0, 1)', math.atan2(0, 1), 0)
-testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
-testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
-
-print 'ceil'
-testit('ceil(0.5)', math.ceil(0.5), 1)
-testit('ceil(1.0)', math.ceil(1.0), 1)
-testit('ceil(1.5)', math.ceil(1.5), 2)
-testit('ceil(-0.5)', math.ceil(-0.5), 0)
-testit('ceil(-1.0)', math.ceil(-1.0), -1)
-testit('ceil(-1.5)', math.ceil(-1.5), -1)
-
-print 'cos'
-testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
-testit('cos(0)', math.cos(0), 1)
-testit('cos(pi/2)', math.cos(math.pi/2), 0)
-testit('cos(pi)', math.cos(math.pi), -1)
-
-print 'cosh'
-testit('cosh(0)', math.cosh(0), 1)
-testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
-
-print 'degrees'
-testit('degrees(pi)', math.degrees(math.pi), 180.0)
-testit('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
-testit('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
-
-print 'exp'
-testit('exp(-1)', math.exp(-1), 1/math.e)
-testit('exp(0)', math.exp(0), 1)
-testit('exp(1)', math.exp(1), math.e)
-
-print 'fabs'
-testit('fabs(-1)', math.fabs(-1), 1)
-testit('fabs(0)', math.fabs(0), 0)
-testit('fabs(1)', math.fabs(1), 1)
-
-print 'floor'
-testit('floor(0.5)', math.floor(0.5), 0)
-testit('floor(1.0)', math.floor(1.0), 1)
-testit('floor(1.5)', math.floor(1.5), 1)
-testit('floor(-0.5)', math.floor(-0.5), -1)
-testit('floor(-1.0)', math.floor(-1.0), -1)
-testit('floor(-1.5)', math.floor(-1.5), -2)
-
-print 'fmod'
-testit('fmod(10,1)', math.fmod(10,1), 0)
-testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
-testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
-testit('fmod(-10,1)', math.fmod(-10,1), 0)
-testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
-testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
-
-print 'frexp'
-def testfrexp(name, (mant, exp), (emant, eexp)):
- if abs(mant-emant) > eps or exp != eexp:
- raise TestFailed, '%s returned %r, expected %r'%\
- (name, (mant, exp), (emant,eexp))
-
-testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
-testfrexp('frexp(0)', math.frexp(0), (0, 0))
-testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
-testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
-
-print 'hypot'
-testit('hypot(0,0)', math.hypot(0,0), 0)
-testit('hypot(3,4)', math.hypot(3,4), 5)
-
-print 'ldexp'
-testit('ldexp(0,1)', math.ldexp(0,1), 0)
-testit('ldexp(1,1)', math.ldexp(1,1), 2)
-testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
-testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
-
-print 'log'
-testit('log(1/e)', math.log(1/math.e), -1)
-testit('log(1)', math.log(1), 0)
-testit('log(e)', math.log(math.e), 1)
-testit('log(32,2)', math.log(32,2), 5)
-testit('log(10**40, 10)', math.log(10**40, 10), 40)
-testit('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
-
-print 'log10'
-testit('log10(0.1)', math.log10(0.1), -1)
-testit('log10(1)', math.log10(1), 0)
-testit('log10(10)', math.log10(10), 1)
-
-print 'modf'
-def testmodf(name, (v1, v2), (e1, e2)):
- if abs(v1-e1) > eps or abs(v2-e2):
- raise TestFailed, '%s returned %r, expected %r'%\
- (name, (v1,v2), (e1,e2))
-
-testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
-testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
-
-print 'pow'
-testit('pow(0,1)', math.pow(0,1), 0)
-testit('pow(1,0)', math.pow(1,0), 1)
-testit('pow(2,1)', math.pow(2,1), 2)
-testit('pow(2,-1)', math.pow(2,-1), 0.5)
-
-print 'radians'
-testit('radians(180)', math.radians(180), math.pi)
-testit('radians(90)', math.radians(90), math.pi/2)
-testit('radians(-45)', math.radians(-45), -math.pi/4)
-
-print 'sin'
-testit('sin(0)', math.sin(0), 0)
-testit('sin(pi/2)', math.sin(math.pi/2), 1)
-testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
-
-print 'sinh'
-testit('sinh(0)', math.sinh(0), 0)
-testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
-testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
-
-print 'sqrt'
-testit('sqrt(0)', math.sqrt(0), 0)
-testit('sqrt(1)', math.sqrt(1), 1)
-testit('sqrt(4)', math.sqrt(4), 2)
-
-print 'tan'
-testit('tan(0)', math.tan(0), 0)
-testit('tan(pi/4)', math.tan(math.pi/4), 1)
-testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
-
-print 'tanh'
-testit('tanh(0)', math.tanh(0), 0)
-testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
-
-# RED_FLAG 16-Oct-2000 Tim
-# While 2.0 is more consistent about exceptions than previous releases, it
-# still fails this part of the test on some platforms. For now, we only
-# *run* test_exceptions() in verbose mode, so that this isn't normally
-# tested.
-
-def test_exceptions():
- print 'exceptions'
- try:
- x = math.exp(-1000000000)
- except:
- # mathmodule.c is failing to weed out underflows from libm, or
- # we've got an fp format with huge dynamic range
- raise TestFailed("underflowing exp() should not have raised "
- "an exception")
- if x != 0:
- raise TestFailed("underflowing exp() should have returned 0")
-
- # If this fails, probably using a strict IEEE-754 conforming libm, and x
- # is +Inf afterwards. But Python wants overflows detected by default.
- try:
- x = math.exp(1000000000)
- except OverflowError:
- pass
- else:
- raise TestFailed("overflowing exp() didn't trigger OverflowError")
-
- # If this fails, it could be a puzzle. One odd possibility is that
- # mathmodule.c's macros are getting confused while comparing
- # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
- # as a result (and so raising OverflowError instead).
- try:
- x = math.sqrt(-1.0)
- except ValueError:
- pass
- else:
- raise TestFailed("sqrt(-1) didn't raise ValueError")
-
-if verbose:
- test_exceptions()
+class MathTests(unittest.TestCase):
+
+ def ftest(self, name, value, expected):
+ if abs(value-expected) > eps:
+ self.fail('%s returned %f, expected %f'%\
+ (name, value, expected))
+
+ def testConstants(self):
+ self.ftest('pi', math.pi, 3.1415926)
+ self.ftest('e', math.e, 2.7182818)
+
+ def testAcos(self):
+ self.assertRaises(TypeError, math.acos)
+ self.ftest('acos(-1)', math.acos(-1), math.pi)
+ self.ftest('acos(0)', math.acos(0), math.pi/2)
+ self.ftest('acos(1)', math.acos(1), 0)
+
+ def testAsin(self):
+ self.assertRaises(TypeError, math.asin)
+ self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
+ self.ftest('asin(0)', math.asin(0), 0)
+ self.ftest('asin(1)', math.asin(1), math.pi/2)
+
+ def testAtan(self):
+ self.assertRaises(TypeError, math.atan)
+ self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
+ self.ftest('atan(0)', math.atan(0), 0)
+ self.ftest('atan(1)', math.atan(1), math.pi/4)
+
+ def testAtan2(self):
+ self.assertRaises(TypeError, math.atan2)
+ self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
+ self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
+ self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
+ self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
+ self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
+
+ def testCeil(self):
+ self.assertRaises(TypeError, math.ceil)
+ self.ftest('ceil(0.5)', math.ceil(0.5), 1)
+ self.ftest('ceil(1.0)', math.ceil(1.0), 1)
+ self.ftest('ceil(1.5)', math.ceil(1.5), 2)
+ self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
+ self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
+ self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
+
+ def testCos(self):
+ self.assertRaises(TypeError, math.cos)
+ self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
+ self.ftest('cos(0)', math.cos(0), 1)
+ self.ftest('cos(pi/2)', math.cos(math.pi/2), 0)
+ self.ftest('cos(pi)', math.cos(math.pi), -1)
+
+ def testCosh(self):
+ self.assertRaises(TypeError, math.cosh)
+ self.ftest('cosh(0)', math.cosh(0), 1)
+ self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
+
+ def testDegrees(self):
+ self.assertRaises(TypeError, math.degrees)
+ self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
+ self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
+ self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
+
+ def testExp(self):
+ self.assertRaises(TypeError, math.exp)
+ self.ftest('exp(-1)', math.exp(-1), 1/math.e)
+ self.ftest('exp(0)', math.exp(0), 1)
+ self.ftest('exp(1)', math.exp(1), math.e)
+
+ def testFabs(self):
+ self.assertRaises(TypeError, math.fabs)
+ self.ftest('fabs(-1)', math.fabs(-1), 1)
+ self.ftest('fabs(0)', math.fabs(0), 0)
+ self.ftest('fabs(1)', math.fabs(1), 1)
+
+ def testFloor(self):
+ self.assertRaises(TypeError, math.floor)
+ self.ftest('floor(0.5)', math.floor(0.5), 0)
+ self.ftest('floor(1.0)', math.floor(1.0), 1)
+ self.ftest('floor(1.5)', math.floor(1.5), 1)
+ self.ftest('floor(-0.5)', math.floor(-0.5), -1)
+ self.ftest('floor(-1.0)', math.floor(-1.0), -1)
+ self.ftest('floor(-1.5)', math.floor(-1.5), -2)
+
+ def testFmod(self):
+ self.assertRaises(TypeError, math.fmod)
+ self.ftest('fmod(10,1)', math.fmod(10,1), 0)
+ self.ftest('fmod(10,0.5)', math.fmod(10,0.5), 0)
+ self.ftest('fmod(10,1.5)', math.fmod(10,1.5), 1)
+ self.ftest('fmod(-10,1)', math.fmod(-10,1), 0)
+ self.ftest('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
+ self.ftest('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
+
+ def testFrexp(self):
+ self.assertRaises(TypeError, math.frexp)
+
+ def testfrexp(name, (mant, exp), (emant, eexp)):
+ if abs(mant-emant) > eps or exp != eexp:
+ self.fail('%s returned %r, expected %r'%\
+ (name, (mant, exp), (emant,eexp)))
+
+ testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
+ testfrexp('frexp(0)', math.frexp(0), (0, 0))
+ testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
+ testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
+
+ def testHypot(self):
+ self.assertRaises(TypeError, math.hypot)
+ self.ftest('hypot(0,0)', math.hypot(0,0), 0)
+ self.ftest('hypot(3,4)', math.hypot(3,4), 5)
+
+ def testLdexp(self):
+ self.assertRaises(TypeError, math.ldexp)
+ self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
+ self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
+ self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
+ self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
+
+ def testLog(self):
+ self.assertRaises(TypeError, math.log)
+ self.ftest('log(1/e)', math.log(1/math.e), -1)
+ self.ftest('log(1)', math.log(1), 0)
+ self.ftest('log(e)', math.log(math.e), 1)
+ self.ftest('log(32,2)', math.log(32,2), 5)
+ self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
+ self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
+
+ def testLog10(self):
+ self.assertRaises(TypeError, math.log10)
+ self.ftest('log10(0.1)', math.log10(0.1), -1)
+ self.ftest('log10(1)', math.log10(1), 0)
+ self.ftest('log10(10)', math.log10(10), 1)
+
+ def testModf(self):
+ self.assertRaises(TypeError, math.modf)
+
+ def testmodf(name, (v1, v2), (e1, e2)):
+ if abs(v1-e1) > eps or abs(v2-e2):
+ self.fail('%s returned %r, expected %r'%\
+ (name, (v1,v2), (e1,e2)))
+
+ testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
+ testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
+
+ def testPow(self):
+ self.assertRaises(TypeError, math.pow)
+ self.ftest('pow(0,1)', math.pow(0,1), 0)
+ self.ftest('pow(1,0)', math.pow(1,0), 1)
+ self.ftest('pow(2,1)', math.pow(2,1), 2)
+ self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
+
+ def testRadians(self):
+ self.assertRaises(TypeError, math.radians)
+ self.ftest('radians(180)', math.radians(180), math.pi)
+ self.ftest('radians(90)', math.radians(90), math.pi/2)
+ self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
+
+ def testSin(self):
+ self.assertRaises(TypeError, math.sin)
+ self.ftest('sin(0)', math.sin(0), 0)
+ self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
+ self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
+
+ def testSinh(self):
+ self.assertRaises(TypeError, math.sinh)
+ self.ftest('sinh(0)', math.sinh(0), 0)
+ self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
+ self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
+
+ def testSqrt(self):
+ self.assertRaises(TypeError, math.sqrt)
+ self.ftest('sqrt(0)', math.sqrt(0), 0)
+ self.ftest('sqrt(1)', math.sqrt(1), 1)
+ self.ftest('sqrt(4)', math.sqrt(4), 2)
+
+ def testTan(self):
+ self.assertRaises(TypeError, math.tan)
+ self.ftest('tan(0)', math.tan(0), 0)
+ self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
+ self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
+
+ def testTanh(self):
+ self.assertRaises(TypeError, math.tanh)
+ self.ftest('tanh(0)', math.tanh(0), 0)
+ self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
+
+ # RED_FLAG 16-Oct-2000 Tim
+ # While 2.0 is more consistent about exceptions than previous releases, it
+ # still fails this part of the test on some platforms. For now, we only
+ # *run* test_exceptions() in verbose mode, so that this isn't normally
+ # tested.
+
+ if verbose:
+ def test_exceptions(self):
+ try:
+ x = math.exp(-1000000000)
+ except:
+ # mathmodule.c is failing to weed out underflows from libm, or
+ # we've got an fp format with huge dynamic range
+ self.fail("underflowing exp() should not have raised "
+ "an exception")
+ if x != 0:
+ self.fail("underflowing exp() should have returned 0")
+
+ # If this fails, probably using a strict IEEE-754 conforming libm, and x
+ # is +Inf afterwards. But Python wants overflows detected by default.
+ try:
+ x = math.exp(1000000000)
+ except OverflowError:
+ pass
+ else:
+ self.fail("overflowing exp() didn't trigger OverflowError")
+
+ # If this fails, it could be a puzzle. One odd possibility is that
+ # mathmodule.c's macros are getting confused while comparing
+ # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
+ # as a result (and so raising OverflowError instead).
+ try:
+ x = math.sqrt(-1.0)
+ except ValueError:
+ pass
+ else:
+ self.fail("sqrt(-1) didn't raise ValueError")
+
+
+def test_main():
+ run_unittest(MathTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index d2a2477..0b53823 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -1,190 +1,158 @@
-from test.test_support import verify, vereq, TESTFN
+from test.test_support import TESTFN, run_unittest
import mmap
+import unittest
import os, re
PAGESIZE = mmap.PAGESIZE
-def test_both():
- "Test mmap module on Unix systems and Windows"
+class MmapTests(unittest.TestCase):
- # Create a file to be mmap'ed.
- if os.path.exists(TESTFN):
- os.unlink(TESTFN)
- f = open(TESTFN, 'w+')
+ def setUp(self):
+ if os.path.exists(TESTFN):
+ os.unlink(TESTFN)
- try: # unlink TESTFN no matter what
- # Write 2 pages worth of data to the file
- f.write('\0'* PAGESIZE)
- f.write('foo')
- f.write('\0'* (PAGESIZE-3) )
- f.flush()
- m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
- f.close()
+ def tearDown(self):
+ try:
+ os.unlink(TESTFN)
+ except OSError:
+ pass
- # Simple sanity checks
+ def test_basic(self):
+ # Test mmap module on Unix systems and Windows
- print type(m) # SF bug 128713: segfaulted on Linux
- print ' Position of foo:', m.find('foo') / float(PAGESIZE), 'pages'
- vereq(m.find('foo'), PAGESIZE)
+ # Create a file to be mmap'ed.
+ f = open(TESTFN, 'w+')
+ try:
+ # Write 2 pages worth of data to the file
+ f.write('\0'* PAGESIZE)
+ f.write('foo')
+ f.write('\0'* (PAGESIZE-3) )
+ f.flush()
+ m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
+ f.close()
- print ' Length of file:', len(m) / float(PAGESIZE), 'pages'
- vereq(len(m), 2*PAGESIZE)
+ # Simple sanity checks
- print ' Contents of byte 0:', repr(m[0])
- vereq(m[0], '\0')
- print ' Contents of first 3 bytes:', repr(m[0:3])
- vereq(m[0:3], '\0\0\0')
+ tp = str(type(m)) # SF bug 128713: segfaulted on Linux
+ self.assertEqual(m.find('foo'), PAGESIZE)
- # Modify the file's content
- print "\n Modifying file's content..."
- m[0] = '3'
- m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
+ self.assertEqual(len(m), 2*PAGESIZE)
- # Check that the modification worked
- print ' Contents of byte 0:', repr(m[0])
- vereq(m[0], '3')
- print ' Contents of first 3 bytes:', repr(m[0:3])
- vereq(m[0:3], '3\0\0')
- print ' Contents of second page:', repr(m[PAGESIZE-1 : PAGESIZE + 7])
- vereq(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
+ self.assertEqual(m[0], '\0')
+ self.assertEqual(m[0:3], '\0\0\0')
- m.flush()
+ # Modify the file's content
+ m[0] = '3'
+ m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
- # Test doing a regular expression match in an mmap'ed file
- match = re.search('[A-Za-z]+', m)
- if match is None:
- print ' ERROR: regex match on mmap failed!'
- else:
- start, end = match.span(0)
- length = end - start
-
- print ' Regex match on mmap (page start, length of match):',
- print start / float(PAGESIZE), length
-
- vereq(start, PAGESIZE)
- vereq(end, PAGESIZE + 6)
-
- # test seeking around (try to overflow the seek implementation)
- m.seek(0,0)
- print ' Seek to zeroth byte'
- vereq(m.tell(), 0)
- m.seek(42,1)
- print ' Seek to 42nd byte'
- vereq(m.tell(), 42)
- m.seek(0,2)
- print ' Seek to last byte'
- vereq(m.tell(), len(m))
-
- print ' Try to seek to negative position...'
- try:
- m.seek(-1)
- except ValueError:
- pass
- else:
- verify(0, 'expected a ValueError but did not get it')
+ # Check that the modification worked
+ self.assertEqual(m[0], '3')
+ self.assertEqual(m[0:3], '3\0\0')
+ self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
- print ' Try to seek beyond end of mmap...'
- try:
- m.seek(1,2)
- except ValueError:
- pass
- else:
- verify(0, 'expected a ValueError but did not get it')
+ m.flush()
- print ' Try to seek to negative position...'
- try:
- m.seek(-len(m)-1,2)
- except ValueError:
- pass
- else:
- verify(0, 'expected a ValueError but did not get it')
+ # Test doing a regular expression match in an mmap'ed file
+ match = re.search('[A-Za-z]+', m)
+ if match is None:
+ self.fail('regex match on mmap failed!')
+ else:
+ start, end = match.span(0)
+ length = end - start
- # Try resizing map
- print ' Attempting resize()'
- try:
- m.resize(512)
- except SystemError:
- # resize() not supported
- # No messages are printed, since the output of this test suite
- # would then be different across platforms.
- pass
- else:
- # resize() is supported
- verify(len(m) == 512,
- "len(m) is %d, but expecting 512" % (len(m),) )
- # Check that we can no longer seek beyond the new size.
+ self.assertEqual(start, PAGESIZE)
+ self.assertEqual(end, PAGESIZE + 6)
+
+ # test seeking around (try to overflow the seek implementation)
+ m.seek(0,0)
+ self.assertEqual(m.tell(), 0)
+ m.seek(42,1)
+ self.assertEqual(m.tell(), 42)
+ m.seek(0,2)
+ self.assertEqual(m.tell(), len(m))
+
+ # Try to seek to negative position...
+ self.assertRaises(ValueError, m.seek, -1)
+
+ # Try to seek beyond end of mmap...
+ self.assertRaises(ValueError, m.seek, 1, 2)
+
+ # Try to seek to negative position...
+ self.assertRaises(ValueError, m.seek, -len(m)-1, 2)
+
+ # Try resizing map
try:
- m.seek(513,0)
- except ValueError:
+ m.resize(512)
+ except SystemError:
+ # resize() not supported
+ # No messages are printed, since the output of this test suite
+ # would then be different across platforms.
pass
else:
- verify(0, 'Could seek beyond the new size')
+ # resize() is supported
+ self.assertEqual(len(m), 512)
+ # Check that we can no longer seek beyond the new size.
+ self.assertRaises(ValueError, m.seek, 513, 0)
+
+ # Check that the underlying file is truncated too
+ # (bug #728515)
+ f = open(TESTFN)
+ f.seek(0, 2)
+ self.assertEqual(f.tell(), 512)
+ f.close()
+ self.assertEqual(m.size(), 512)
- # Check that the underlying file is truncated too
- # (bug #728515)
- f = open(TESTFN)
- f.seek(0, 2)
- verify(f.tell() == 512, 'Underlying file not truncated')
- f.close()
- verify(m.size() == 512, 'New size not reflected in file')
-
- m.close()
+ m.close()
- finally:
- try:
- f.close()
- except OSError:
- pass
- try:
- os.unlink(TESTFN)
- except OSError:
- pass
+ finally:
+ try:
+ f.close()
+ except OSError:
+ pass
- # Test for "access" keyword parameter
- try:
+ def test_access_parameter(self):
+ # Test for "access" keyword parameter
mapsize = 10
- print " Creating", mapsize, "byte test data file."
open(TESTFN, "wb").write("a"*mapsize)
- print " Opening mmap with access=ACCESS_READ"
f = open(TESTFN, "rb")
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
- verify(m[:] == 'a'*mapsize, "Readonly memory map data incorrect.")
+ self.assertEqual(m[:], 'a'*mapsize, "Readonly memory map data incorrect.")
- print " Ensuring that readonly mmap can't be slice assigned."
+ # Ensuring that readonly mmap can't be slice assigned
try:
m[:] = 'b'*mapsize
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be item assigned."
+ # Ensuring that readonly mmap can't be item assigned
try:
m[0] = 'b'
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be write() to."
+ # Ensuring that readonly mmap can't be write() to
try:
m.seek(0,0)
m.write('abc')
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be write_byte() to."
+ # Ensuring that readonly mmap can't be write_byte() to
try:
m.seek(0,0)
m.write_byte('d')
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be resized."
+ # Ensuring that readonly mmap can't be resized
try:
m.resize(2*mapsize)
except SystemError: # resize is not universally supported
@@ -192,12 +160,12 @@ def test_both():
except TypeError:
pass
else:
- verify(0, "Able to resize readonly memory map")
+ self.fail("Able to resize readonly memory map")
del m, f
- verify(open(TESTFN, "rb").read() == 'a'*mapsize,
+ self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize,
"Readonly memory map data file was modified")
- print " Opening mmap with size too big"
+ # Opening mmap with size too big
import sys
f = open(TESTFN, "r+b")
try:
@@ -208,11 +176,11 @@ def test_both():
# later tests assume that the length hasn't changed. We need to
# repair that.
if sys.platform.startswith('win'):
- verify(0, "Opening mmap with size+1 should work on Windows.")
+ self.fail("Opening mmap with size+1 should work on Windows.")
else:
# we expect a ValueError on Unix, but not on Windows
if not sys.platform.startswith('win'):
- verify(0, "Opening mmap with size+1 should raise ValueError.")
+ self.fail("Opening mmap with size+1 should raise ValueError.")
m.close()
f.close()
if sys.platform.startswith('win'):
@@ -221,12 +189,12 @@ def test_both():
f.truncate(mapsize)
f.close()
- print " Opening mmap with access=ACCESS_WRITE"
+ # Opening mmap with access=ACCESS_WRITE
f = open(TESTFN, "r+b")
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
- print " Modifying write-through memory map."
+ # Modifying write-through memory map
m[:] = 'c'*mapsize
- verify(m[:] == 'c'*mapsize,
+ self.assertEqual(m[:], 'c'*mapsize,
"Write-through memory map memory not updated properly.")
m.flush()
m.close()
@@ -234,66 +202,45 @@ def test_both():
f = open(TESTFN, 'rb')
stuff = f.read()
f.close()
- verify(stuff == 'c'*mapsize,
+ self.assertEqual(stuff, 'c'*mapsize,
"Write-through memory map data file not updated properly.")
- print " Opening mmap with access=ACCESS_COPY"
+ # Opening mmap with access=ACCESS_COPY
f = open(TESTFN, "r+b")
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
- print " Modifying copy-on-write memory map."
+ # Modifying copy-on-write memory map
m[:] = 'd'*mapsize
- verify(m[:] == 'd' * mapsize,
+ self.assertEqual(m[:], 'd' * mapsize,
"Copy-on-write memory map data not written correctly.")
m.flush()
- verify(open(TESTFN, "rb").read() == 'c'*mapsize,
+ self.assertEqual(open(TESTFN, "rb").read(), 'c'*mapsize,
"Copy-on-write test data file should not be modified.")
- try:
- print " Ensuring copy-on-write maps cannot be resized."
- m.resize(2*mapsize)
- except TypeError:
- pass
- else:
- verify(0, "Copy-on-write mmap resize did not raise exception.")
+ # Ensuring copy-on-write maps cannot be resized
+ self.assertRaises(TypeError, m.resize, 2*mapsize)
del m, f
- try:
- print " Ensuring invalid access parameter raises exception."
- f = open(TESTFN, "r+b")
- m = mmap.mmap(f.fileno(), mapsize, access=4)
- except ValueError:
- pass
- else:
- verify(0, "Invalid access code should have raised exception.")
+
+ # Ensuring invalid access parameter raises exception
+ f = open(TESTFN, "r+b")
+ self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4)
+ f.close()
if os.name == "posix":
# Try incompatible flags, prot and access parameters.
f = open(TESTFN, "r+b")
- try:
- m = mmap.mmap(f.fileno(), mapsize, flags=mmap.MAP_PRIVATE,
+ self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize,
+ flags=mmap.MAP_PRIVATE,
prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
- except ValueError:
- pass
- else:
- verify(0, "Incompatible parameters should raise ValueError.")
f.close()
- finally:
- try:
- os.unlink(TESTFN)
- except OSError:
- pass
- print ' Try opening a bad file descriptor...'
- try:
- mmap.mmap(-2, 4096)
- except mmap.error:
- pass
- else:
- verify(0, 'expected a mmap.error but did not get it')
+ def test_bad_file_desc(self):
+ # Try opening a bad file descriptor...
+ self.assertRaises(mmap.error, mmap.mmap, -2, 4096)
- # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
- # searching for data with embedded \0 bytes didn't work.
- f = open(TESTFN, 'w+')
+ def test_tougher_find(self):
+ # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
+ # searching for data with embedded \0 bytes didn't work.
+ f = open(TESTFN, 'w+')
- try: # unlink TESTFN no matter what
data = 'aabaac\x00deef\x00\x00aa\x00'
n = len(data)
f.write(data)
@@ -304,17 +251,14 @@ def test_both():
for start in range(n+1):
for finish in range(start, n+1):
slice = data[start : finish]
- vereq(m.find(slice), data.find(slice))
- vereq(m.find(slice + 'x'), -1)
+ self.assertEqual(m.find(slice), data.find(slice))
+ self.assertEqual(m.find(slice + 'x'), -1)
m.close()
- finally:
- os.unlink(TESTFN)
+ def test_double_close(self):
+ # make sure a double close doesn't crash on Solaris (Bug# 665913)
+ f = open(TESTFN, 'w+')
- # make sure a double close doesn't crash on Solaris (Bug# 665913)
- f = open(TESTFN, 'w+')
-
- try: # unlink TESTFN no matter what
f.write(2**16 * 'a') # Arbitrary character
f.close()
@@ -324,72 +268,46 @@ def test_both():
mf.close()
f.close()
- finally:
- os.unlink(TESTFN)
-
- # test mapping of entire file by passing 0 for map length
- if hasattr(os, "stat"):
- print " Ensuring that passing 0 as map length sets map size to current file size."
- f = open(TESTFN, "w+")
+ def test_entire_file(self):
+ # test mapping of entire file by passing 0 for map length
+ if hasattr(os, "stat"):
+ f = open(TESTFN, "w+")
- try:
f.write(2**16 * 'm') # Arbitrary character
f.close()
f = open(TESTFN, "rb+")
mf = mmap.mmap(f.fileno(), 0)
- verify(len(mf) == 2**16, "Map size should equal file size.")
- vereq(mf.read(2**16), 2**16 * "m")
+ self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
+ self.assertEqual(mf.read(2**16), 2**16 * "m")
mf.close()
f.close()
- finally:
- os.unlink(TESTFN)
-
- # test mapping of entire file by passing 0 for map length
- if hasattr(os, "stat"):
- print " Ensuring that passing 0 as map length sets map size to current file size."
- f = open(TESTFN, "w+")
- try:
- f.write(2**16 * 'm') # Arbitrary character
- f.close()
-
- f = open(TESTFN, "rb+")
- mf = mmap.mmap(f.fileno(), 0)
- verify(len(mf) == 2**16, "Map size should equal file size.")
- vereq(mf.read(2**16), 2**16 * "m")
- mf.close()
- f.close()
-
- finally:
- os.unlink(TESTFN)
-
- # make move works everywhere (64-bit format problem earlier)
- f = open(TESTFN, 'w+')
+ def test_move(self):
+ # make move works everywhere (64-bit format problem earlier)
+ f = open(TESTFN, 'w+')
- try: # unlink TESTFN no matter what
f.write("ABCDEabcde") # Arbitrary character
f.flush()
mf = mmap.mmap(f.fileno(), 10)
mf.move(5, 0, 5)
- verify(mf[:] == "ABCDEABCDE", "Map move should have duplicated front 5")
+ self.assertEqual(mf[:], "ABCDEABCDE", "Map move should have duplicated front 5")
mf.close()
f.close()
- finally:
- os.unlink(TESTFN)
+ def test_anonymous(self):
+ # anonymous mmap.mmap(-1, PAGE)
+ m = mmap.mmap(-1, PAGESIZE)
+ for x in xrange(PAGESIZE):
+ self.assertEqual(m[x], '\0', "anonymously mmap'ed contents should be zero")
-def test_anon():
- print " anonymous mmap.mmap(-1, PAGESIZE)..."
- m = mmap.mmap(-1, PAGESIZE)
- for x in xrange(PAGESIZE):
- verify(m[x] == '\0', "anonymously mmap'ed contents should be zero")
+ for x in xrange(PAGESIZE):
+ m[x] = ch = chr(x & 255)
+ self.assertEqual(m[x], ch)
- for x in xrange(PAGESIZE):
- m[x] = ch = chr(x & 255)
- vereq(m[x], ch)
+def test_main():
+ run_unittest(MmapTests)
-test_both()
-test_anon()
-print ' Test passed'
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py
index 0b8e451..7da241b 100644
--- a/Lib/test/test_modulefinder.py
+++ b/Lib/test/test_modulefinder.py
@@ -50,7 +50,7 @@ b/__init__.py
maybe_test_new = [
"a.module",
["a", "a.module", "sys",
- "b"],
+ "b", "__future__"],
["c"], ["b.something"],
"""\
a/__init__.py
@@ -58,6 +58,7 @@ a/module.py
from b import something
from c import something
b/__init__.py
+ from __future__ import absolute_import
from sys import *
"""]
@@ -86,12 +87,13 @@ absolute_import_test = [
"a.module",
["a", "a.module",
"b", "b.x", "b.y", "b.z",
- "sys", "exceptions"],
+ "__future__", "sys", "exceptions"],
["blahblah", "z"], [],
"""\
mymodule.py
a/__init__.py
a/module.py
+ from __future__ import absolute_import
import sys # sys
import blahblah # fails
import exceptions # exceptions
@@ -115,7 +117,8 @@ b/z.py
relative_import_test = [
"a.module",
- ["a", "a.module",
+ ["__future__",
+ "a", "a.module",
"a.b", "a.b.y", "a.b.z",
"a.b.c", "a.b.c.moduleC",
"a.b.c.d", "a.b.c.e",
@@ -127,6 +130,7 @@ mymodule.py
a/__init__.py
from .b import y, z # a.b.y, a.b.z
a/module.py
+ from __future__ import absolute_import # __future__
import exceptions # exceptions
a/exceptions.py
a/sys.py
@@ -253,6 +257,7 @@ class ModuleFinderTest(unittest.TestCase):
self._do_test(relative_import_test_2)
def test_main():
+ distutils.log.set_threshold(distutils.log.WARN)
test_support.run_unittest(ModuleFinderTest)
if __name__ == "__main__":
diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py
index 95f4b38..fb7f82d 100644
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -202,6 +202,22 @@ class Test_ISO2022(unittest.TestCase):
uni = u':hu4:unit\xe9 de famille'
self.assertEqual(iso2022jp2.decode('iso2022-jp-2'), uni)
+ def test_iso2022_jp_g0(self):
+ self.failIf('\x0e' in u'\N{SOFT HYPHEN}'.encode('iso-2022-jp-2'))
+ for encoding in ('iso-2022-jp-2004', 'iso-2022-jp-3'):
+ e = u'\u3406'.encode(encoding)
+ self.failIf(filter(lambda x: x >= '\x80', e))
+
+ def test_bug1572832(self):
+ if sys.maxunicode >= 0x10000:
+ myunichr = unichr
+ else:
+ myunichr = lambda x: unichr(0xD7C0+(x>>10)) + unichr(0xDC00+(x&0x3FF))
+
+ for x in xrange(0x10000, 0x110000):
+ # Any ISO 2022 codec will cause the segfault
+ myunichr(x).encode('iso_2022_jp', 'ignore')
+
def test_main():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(Test_MultibyteCodec))
diff --git a/Lib/test/test_mutants.py b/Lib/test/test_mutants.py
index 8afda75..6215226 100644
--- a/Lib/test/test_mutants.py
+++ b/Lib/test/test_mutants.py
@@ -92,8 +92,8 @@ class Horrid:
##self.hashcode = random.randrange(1000000000)
def __hash__(self):
- ##return self.hashcode
return 42
+ return self.hashcode
def __eq__(self, other):
maybe_mutate() # The point of the test.
diff --git a/Lib/test/test_new.py b/Lib/test/test_new.py
index 3c16bf5..e90fd66 100644
--- a/Lib/test/test_new.py
+++ b/Lib/test/test_new.py
@@ -47,6 +47,14 @@ except TypeError:
else:
raise TestFailed, "dangerous instance method creation allowed"
+# Verify that instancemethod() doesn't allow keyword args
+try:
+ new.instancemethod(break_yolks, c, kw=1)
+except TypeError:
+ pass
+else:
+ raise TestFailed, "instancemethod shouldn't accept keyword args"
+
# It's unclear what the semantics should be for a code object compiled at
# module scope, but bound and run in a function. In CPython, `c' is global
# (by accident?) while in Jython, `c' is local. The intent of the test
diff --git a/Lib/test/test_nis.py b/Lib/test/test_nis.py
index f5224fe..590868f 100644
--- a/Lib/test/test_nis.py
+++ b/Lib/test/test_nis.py
@@ -1,32 +1,41 @@
-from test.test_support import verbose, TestFailed, TestSkipped
+from test.test_support import verbose, run_unittest
+import unittest
import nis
-print 'nis.maps()'
-try:
- maps = nis.maps()
-except nis.error, msg:
- # NIS is probably not active, so this test isn't useful
- if verbose:
- raise TestFailed, msg
- # only do this if running under the regression suite
- raise TestSkipped, msg
+class NisTests(unittest.TestCase):
+ def test_maps(self):
+ try:
+ maps = nis.maps()
+ except nis.error, msg:
+ # NIS is probably not active, so this test isn't useful
+ if verbose:
+ self.fail("(failing because of verbose mode) %s" % msg)
+ return
+ try:
+ # On some systems, this map is only accessible to the
+ # super user
+ maps.remove("passwd.adjunct.byname")
+ except ValueError:
+ pass
-done = 0
-for nismap in maps:
- if verbose:
- print nismap
- mapping = nis.cat(nismap)
- for k, v in mapping.items():
- if verbose:
- print ' ', k, v
- if not k:
- continue
- if nis.match(k, nismap) != v:
- print "NIS match failed for key `%s' in map `%s'" % (k, nismap)
- else:
- # just test the one key, otherwise this test could take a
- # very long time
- done = 1
- break
- if done:
- break
+ done = 0
+ for nismap in maps:
+ mapping = nis.cat(nismap)
+ for k, v in mapping.items():
+ if not k:
+ continue
+ if nis.match(k, nismap) != v:
+ self.fail("NIS match failed for key `%s' in map `%s'" % (k, nismap))
+ else:
+ # just test the one key, otherwise this test could take a
+ # very long time
+ done = 1
+ break
+ if done:
+ break
+
+def test_main():
+ run_unittest(NisTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py
index 742267f..1a2f5d6 100644
--- a/Lib/test/test_opcodes.py
+++ b/Lib/test/test_opcodes.py
@@ -1,101 +1,110 @@
# Python test set -- part 2, opcodes
-from test.test_support import TestFailed
-
-
-print '2. Opcodes'
-print 'XXX Not yet fully implemented'
-
-print '2.1 try inside for loop'
-n = 0
-for i in range(10):
- n = n+i
- try: 1/0
- except NameError: pass
- except ZeroDivisionError: pass
- except TypeError: pass
- try: pass
- except: pass
- try: pass
- finally: pass
- n = n+i
-if n != 90:
- raise TestFailed, 'try inside for'
-
-
-print '2.2 raise class exceptions'
-
-class AClass(Exception): pass
-class BClass(AClass): pass
-class CClass(Exception): pass
-class DClass(AClass):
- def __init__(self, ignore):
- pass
-
-try: raise AClass()
-except: pass
-
-try: raise AClass()
-except AClass: pass
-
-try: raise BClass()
-except AClass: pass
-
-try: raise BClass()
-except CClass: raise TestFailed
-except: pass
-
-a = AClass()
-b = BClass()
-
-try: raise AClass, b
-except BClass, v:
- if v != b: raise TestFailed, "v!=b"
-else: raise TestFailed, "no exception"
-
-try: raise b
-except AClass, v:
- if v != b: raise TestFailed, "v!=b AClass"
-
-# not enough arguments
-##try: raise BClass, a
-##except TypeError: pass
-
-try: raise DClass, a
-except DClass, v:
- if not isinstance(v, DClass):
- raise TestFailed, "v not DClass"
-
-print '2.3 comparing function objects'
-
-f = eval('lambda: None')
-g = eval('lambda: None')
-if f == g: raise TestFailed, "functions should not be same"
-
-f = eval('lambda a: a')
-g = eval('lambda a: a')
-if f == g: raise TestFailed, "functions should not be same"
-
-f = eval('lambda a=1: a')
-g = eval('lambda a=1: a')
-if f == g: raise TestFailed, "functions should not be same"
-
-f = eval('lambda: 0')
-g = eval('lambda: 1')
-if f == g: raise TestFailed
-
-f = eval('lambda: None')
-g = eval('lambda a: None')
-if f == g: raise TestFailed
-
-f = eval('lambda a: None')
-g = eval('lambda b: None')
-if f == g: raise TestFailed
-
-f = eval('lambda a: None')
-g = eval('lambda a=None: None')
-if f == g: raise TestFailed
-
-f = eval('lambda a=0: None')
-g = eval('lambda a=1: None')
-if f == g: raise TestFailed
+from test.test_support import run_unittest
+import unittest
+
+class OpcodeTest(unittest.TestCase):
+
+ def test_try_inside_for_loop(self):
+ n = 0
+ for i in range(10):
+ n = n+i
+ try: 1/0
+ except NameError: pass
+ except ZeroDivisionError: pass
+ except TypeError: pass
+ try: pass
+ except: pass
+ try: pass
+ finally: pass
+ n = n+i
+ if n != 90:
+ self.fail('try inside for')
+
+ def test_raise_class_exceptions(self):
+
+ class AClass(Exception): pass
+ class BClass(AClass): pass
+ class CClass(Exception): pass
+ class DClass(AClass):
+ def __init__(self, ignore):
+ pass
+
+ try: raise AClass()
+ except: pass
+
+ try: raise AClass()
+ except AClass: pass
+
+ try: raise BClass()
+ except AClass: pass
+
+ try: raise BClass()
+ except CClass: self.fail()
+ except: pass
+
+ a = AClass()
+ b = BClass()
+
+ try: raise AClass, b
+ except BClass, v:
+ if v != b: self.fail("v!=b")
+ else: self.fail("no exception")
+
+ try: raise b
+ except AClass, v:
+ if v != b: self.fail("v!=b AClass")
+ else:
+ self.fail("no exception")
+
+ # not enough arguments
+ ##try: raise BClass, a
+ ##except TypeError: pass
+ ##else: self.fail("no exception")
+
+ try: raise DClass, a
+ except DClass, v:
+ self.assert_(isinstance(v, DClass))
+ else:
+ self.fail("no exception")
+
+ def test_compare_function_objects(self):
+
+ f = eval('lambda: None')
+ g = eval('lambda: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a: a')
+ g = eval('lambda a: a')
+ self.failIf(f == g)
+
+ f = eval('lambda a=1: a')
+ g = eval('lambda a=1: a')
+ self.failIf(f == g)
+
+ f = eval('lambda: 0')
+ g = eval('lambda: 1')
+ self.failIf(f == g)
+
+ f = eval('lambda: None')
+ g = eval('lambda a: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a: None')
+ g = eval('lambda b: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a: None')
+ g = eval('lambda a=None: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a=0: None')
+ g = eval('lambda a=1: None')
+ self.failIf(f == g)
+
+
+def test_main():
+ run_unittest(OpcodeTest)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_openpty.py b/Lib/test/test_openpty.py
index a8b8550..6471f58 100644
--- a/Lib/test/test_openpty.py
+++ b/Lib/test/test_openpty.py
@@ -1,19 +1,23 @@
# Test to see if openpty works. (But don't worry if it isn't available.)
-import os
-from test.test_support import verbose, TestFailed, TestSkipped
+import os, unittest
+from test.test_support import run_unittest, TestSkipped
-try:
- if verbose:
- print "Calling os.openpty()"
- master, slave = os.openpty()
- if verbose:
- print "(master, slave) = (%d, %d)"%(master, slave)
-except AttributeError:
+if not hasattr(os, "openpty"):
raise TestSkipped, "No openpty() available."
-if not os.isatty(slave):
- raise TestFailed, "Slave-end of pty is not a terminal."
-os.write(slave, 'Ping!')
-print os.read(master, 1024)
+class OpenptyTest(unittest.TestCase):
+ def test(self):
+ master, slave = os.openpty()
+ if not os.isatty(slave):
+ self.fail("Slave-end of pty is not a terminal.")
+
+ os.write(slave, 'Ping!')
+ self.assertEqual(os.read(master, 1024), 'Ping!')
+
+def test_main():
+ run_unittest(OpenptyTest)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index bf0e196..1c87d06 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -223,6 +223,23 @@ class StatAttributeTests(unittest.TestCase):
except TypeError:
pass
+ def test_utime_dir(self):
+ delta = 1000000
+ st = os.stat(test_support.TESTFN)
+ # round to int, because some systems may support sub-second
+ # time stamps in stat, but not in utime.
+ os.utime(test_support.TESTFN, (st.st_atime, int(st.st_mtime-delta)))
+ st2 = os.stat(test_support.TESTFN)
+ self.assertEquals(st2.st_mtime, int(st.st_mtime-delta))
+
+ # Restrict test to Win32, since there is no guarantee other
+ # systems support centiseconds
+ if sys.platform == 'win32':
+ def test_1565150(self):
+ t1 = 1159195039.25
+ os.utime(self.fname, (t1, t1))
+ self.assertEquals(os.stat(self.fname).st_mtime, t1)
+
from test import mapping_tests
class EnvironTests(mapping_tests.BasicTestMappingProtocol):
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index 96384cd..0bf1218 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -183,6 +183,44 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
def test_assert(self):
self.check_suite("assert alo < ahi and blo < bhi\n")
+ def test_position(self):
+ # An absolutely minimal test of position information. Better
+ # tests would be a big project.
+ code = "def f(x):\n return x + 1\n"
+ st1 = parser.suite(code)
+ st2 = st1.totuple(line_info=1, col_info=1)
+
+ def walk(tree):
+ node_type = tree[0]
+ next = tree[1]
+ if isinstance(next, tuple):
+ for elt in tree[1:]:
+ for x in walk(elt):
+ yield x
+ else:
+ yield tree
+
+ terminals = list(walk(st2))
+ self.assertEqual([
+ (1, 'def', 1, 0),
+ (1, 'f', 1, 4),
+ (7, '(', 1, 5),
+ (1, 'x', 1, 6),
+ (8, ')', 1, 7),
+ (11, ':', 1, 8),
+ (4, '', 1, 9),
+ (5, '', 2, -1),
+ (1, 'return', 2, 4),
+ (1, 'x', 2, 11),
+ (14, '+', 2, 13),
+ (2, '1', 2, 15),
+ (4, '', 2, 16),
+ (6, '', 2, -1),
+ (4, '', 2, -1),
+ (0, '', 2, -1)],
+ terminals)
+
+
#
# Second, we take *invalid* trees and make sure we get ParserError
# rejections for them.
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index be7d4e8..779a20a 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -160,6 +160,41 @@ class TestTranforms(unittest.TestCase):
self.assert_('(None)' not in asm)
self.assertEqual(asm.split().count('RETURN_VALUE'), 1)
+ def test_elim_jump_to_return(self):
+ # JUMP_FORWARD to RETURN --> RETURN
+ def f(cond, true_value, false_value):
+ return true_value if cond else false_value
+ asm = disassemble(f)
+ self.assert_('JUMP_FORWARD' not in asm)
+ self.assert_('JUMP_ABSOLUTE' not in asm)
+ self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
+
+ def test_elim_jump_after_return1(self):
+ # Eliminate dead code: jumps immediately after returns can't be reached
+ def f(cond1, cond2):
+ if cond1: return 1
+ if cond2: return 2
+ while 1:
+ return 3
+ while 1:
+ if cond1: return 4
+ return 5
+ return 6
+ asm = disassemble(f)
+ self.assert_('JUMP_FORWARD' not in asm)
+ self.assert_('JUMP_ABSOLUTE' not in asm)
+ self.assertEqual(asm.split().count('RETURN_VALUE'), 6)
+
+ def test_elim_jump_after_return2(self):
+ # Eliminate dead code: jumps immediately after returns can't be reached
+ def f(cond1, cond2):
+ while 1:
+ if cond1: return 4
+ asm = disassemble(f)
+ self.assert_('JUMP_FORWARD' not in asm)
+ # There should be one jump for the while loop.
+ self.assertEqual(asm.split().count('JUMP_ABSOLUTE'), 1)
+ self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
def test_main(verbose=None):
diff --git a/Lib/test/test_pep352.py b/Lib/test/test_pep352.py
index 73cffd2..75610b6 100644
--- a/Lib/test/test_pep352.py
+++ b/Lib/test/test_pep352.py
@@ -15,8 +15,7 @@ class ExceptionClassTests(unittest.TestCase):
self.failUnless(issubclass(Exception, object))
def verify_instance_interface(self, ins):
- for attr in ("args", "message", "__str__", "__unicode__", "__repr__",
- "__getitem__"):
+ for attr in ("args", "message", "__str__", "__repr__", "__getitem__"):
self.failUnless(hasattr(ins, attr), "%s missing %s attribute" %
(ins.__class__.__name__, attr))
diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py
index 3a48bce..60cd3f4 100644
--- a/Lib/test/test_poll.py
+++ b/Lib/test/test_poll.py
@@ -1,7 +1,7 @@
# Test case for the os.poll() function
-import sys, os, select, random
-from test.test_support import verify, verbose, TestSkipped, TESTFN
+import sys, os, select, random, unittest
+from test.test_support import TestSkipped, TESTFN, run_unittest
try:
select.poll
@@ -16,177 +16,141 @@ def find_ready_matching(ready, flag):
match.append(fd)
return match
-def test_poll1():
- """Basic functional test of poll object
-
- Create a bunch of pipe and test that poll works with them.
- """
- print 'Running poll test 1'
- p = select.poll()
-
- NUM_PIPES = 12
- MSG = " This is a test."
- MSG_LEN = len(MSG)
- readers = []
- writers = []
- r2w = {}
- w2r = {}
-
- for i in range(NUM_PIPES):
- rd, wr = os.pipe()
- p.register(rd, select.POLLIN)
- p.register(wr, select.POLLOUT)
- readers.append(rd)
- writers.append(wr)
- r2w[rd] = wr
- w2r[wr] = rd
-
- while writers:
- ready = p.poll()
- ready_writers = find_ready_matching(ready, select.POLLOUT)
- if not ready_writers:
- raise RuntimeError, "no pipes ready for writing"
- wr = random.choice(ready_writers)
- os.write(wr, MSG)
-
- ready = p.poll()
- ready_readers = find_ready_matching(ready, select.POLLIN)
- if not ready_readers:
- raise RuntimeError, "no pipes ready for reading"
- rd = random.choice(ready_readers)
- buf = os.read(rd, MSG_LEN)
- verify(len(buf) == MSG_LEN)
- print buf
- os.close(r2w[rd]) ; os.close( rd )
- p.unregister( r2w[rd] )
- p.unregister( rd )
- writers.remove(r2w[rd])
-
- poll_unit_tests()
- print 'Poll test 1 complete'
-
-def poll_unit_tests():
- # returns NVAL for invalid file descriptor
- FD = 42
- try:
- os.close(FD)
- except OSError:
- pass
- p = select.poll()
- p.register(FD)
- r = p.poll()
- verify(r[0] == (FD, select.POLLNVAL))
-
- f = open(TESTFN, 'w')
- fd = f.fileno()
- p = select.poll()
- p.register(f)
- r = p.poll()
- verify(r[0][0] == fd)
- f.close()
- r = p.poll()
- verify(r[0] == (fd, select.POLLNVAL))
- os.unlink(TESTFN)
-
- # type error for invalid arguments
- p = select.poll()
- try:
- p.register(p)
- except TypeError:
- pass
- else:
- print "Bogus register call did not raise TypeError"
- try:
- p.unregister(p)
- except TypeError:
- pass
- else:
- print "Bogus unregister call did not raise TypeError"
-
- # can't unregister non-existent object
- p = select.poll()
- try:
- p.unregister(3)
- except KeyError:
- pass
- else:
- print "Bogus unregister call did not raise KeyError"
-
- # Test error cases
- pollster = select.poll()
- class Nope:
- pass
-
- class Almost:
- def fileno(self):
- return 'fileno'
-
- try:
- pollster.register( Nope(), 0 )
- except TypeError: pass
- else: print 'expected TypeError exception, not raised'
-
- try:
- pollster.register( Almost(), 0 )
- except TypeError: pass
- else: print 'expected TypeError exception, not raised'
-
-
-# Another test case for poll(). This is copied from the test case for
-# select(), modified to use poll() instead.
-
-def test_poll2():
- print 'Running poll test 2'
- cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
- p = os.popen(cmd, 'r')
- pollster = select.poll()
- pollster.register( p, select.POLLIN )
- for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
- if verbose:
- print 'timeout =', tout
- fdlist = pollster.poll(tout)
- if (fdlist == []):
- continue
- fd, flags = fdlist[0]
- if flags & select.POLLHUP:
- line = p.readline()
- if line != "":
- print 'error: pipe seems to be closed, but still returns data'
- continue
-
- elif flags & select.POLLIN:
- line = p.readline()
- if verbose:
- print repr(line)
- if not line:
- if verbose:
- print 'EOF'
- break
- continue
- else:
- print 'Unexpected return value from select.poll:', fdlist
- p.close()
- print 'Poll test 2 complete'
-
-def test_poll3():
- # test int overflow
- print 'Running poll test 3'
- pollster = select.poll()
- pollster.register(1)
-
- try:
- pollster.poll(1L << 64)
- except OverflowError:
- pass
- else:
- print 'Expected OverflowError with excessive timeout'
-
- x = 2 + 3
- if x != 5:
- print 'Overflow must have occurred'
- print 'Poll test 3 complete'
-
-
-test_poll1()
-test_poll2()
-test_poll3()
+class PollTests(unittest.TestCase):
+
+ def test_poll1(self):
+ # Basic functional test of poll object
+ # Create a bunch of pipe and test that poll works with them.
+
+ p = select.poll()
+
+ NUM_PIPES = 12
+ MSG = " This is a test."
+ MSG_LEN = len(MSG)
+ readers = []
+ writers = []
+ r2w = {}
+ w2r = {}
+
+ for i in range(NUM_PIPES):
+ rd, wr = os.pipe()
+ p.register(rd, select.POLLIN)
+ p.register(wr, select.POLLOUT)
+ readers.append(rd)
+ writers.append(wr)
+ r2w[rd] = wr
+ w2r[wr] = rd
+
+ bufs = []
+
+ while writers:
+ ready = p.poll()
+ ready_writers = find_ready_matching(ready, select.POLLOUT)
+ if not ready_writers:
+ raise RuntimeError, "no pipes ready for writing"
+ wr = random.choice(ready_writers)
+ os.write(wr, MSG)
+
+ ready = p.poll()
+ ready_readers = find_ready_matching(ready, select.POLLIN)
+ if not ready_readers:
+ raise RuntimeError, "no pipes ready for reading"
+ rd = random.choice(ready_readers)
+ buf = os.read(rd, MSG_LEN)
+ self.assertEqual(len(buf), MSG_LEN)
+ bufs.append(buf)
+ os.close(r2w[rd]) ; os.close( rd )
+ p.unregister( r2w[rd] )
+ p.unregister( rd )
+ writers.remove(r2w[rd])
+
+ self.assertEqual(bufs, [MSG] * NUM_PIPES)
+
+ def poll_unit_tests(self):
+ # returns NVAL for invalid file descriptor
+ FD = 42
+ try:
+ os.close(FD)
+ except OSError:
+ pass
+ p = select.poll()
+ p.register(FD)
+ r = p.poll()
+ self.assertEqual(r[0], (FD, select.POLLNVAL))
+
+ f = open(TESTFN, 'w')
+ fd = f.fileno()
+ p = select.poll()
+ p.register(f)
+ r = p.poll()
+ self.assertEqual(r[0][0], fd)
+ f.close()
+ r = p.poll()
+ self.assertEqual(r[0], (fd, select.POLLNVAL))
+ os.unlink(TESTFN)
+
+ # type error for invalid arguments
+ p = select.poll()
+ self.assertRaises(TypeError, p.register, p)
+ self.assertRaises(TypeError, p.unregister, p)
+
+ # can't unregister non-existent object
+ p = select.poll()
+ self.assertRaises(KeyError, p.unregister, 3)
+
+ # Test error cases
+ pollster = select.poll()
+ class Nope:
+ pass
+
+ class Almost:
+ def fileno(self):
+ return 'fileno'
+
+ self.assertRaises(TypeError, pollster.register, Nope(), 0)
+ self.assertRaises(TypeError, pollster.register, Almost(), 0)
+
+ # Another test case for poll(). This is copied from the test case for
+ # select(), modified to use poll() instead.
+
+ def test_poll2(self):
+ cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
+ p = os.popen(cmd, 'r')
+ pollster = select.poll()
+ pollster.register( p, select.POLLIN )
+ for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
+ fdlist = pollster.poll(tout)
+ if (fdlist == []):
+ continue
+ fd, flags = fdlist[0]
+ if flags & select.POLLHUP:
+ line = p.readline()
+ if line != "":
+ self.fail('error: pipe seems to be closed, but still returns data')
+ continue
+
+ elif flags & select.POLLIN:
+ line = p.readline()
+ if not line:
+ break
+ continue
+ else:
+ self.fail('Unexpected return value from select.poll: %s' % fdlist)
+ p.close()
+
+ def test_poll3(self):
+ # test int overflow
+ pollster = select.poll()
+ pollster.register(1)
+
+ self.assertRaises(OverflowError, pollster.poll, 1L << 64)
+
+ x = 2 + 3
+ if x != 5:
+ self.fail('Overflow must have occurred')
+
+def test_main():
+ run_unittest(PollTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 01703b5..7c9d4aa 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -95,6 +95,9 @@ class PyclbrTest(TestCase):
py_item = getattr(module, name)
if isinstance(value, pyclbr.Function):
self.assert_(isinstance(py_item, (FunctionType, BuiltinFunctionType)))
+ if py_item.__module__ != moduleName:
+ continue # skip functions that came from somewhere else
+ self.assertEquals(py_item.__module__, value.module)
else:
self.failUnless(isinstance(py_item, (ClassType, type)))
if py_item.__module__ != moduleName:
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py
index e4e592a..777e85a 100644
--- a/Lib/test/test_scope.py
+++ b/Lib/test/test_scope.py
@@ -1,186 +1,190 @@
-from test.test_support import verify, TestFailed, check_syntax, vereq
+import unittest
+from test.test_support import check_syntax_error, run_unittest
import warnings
+warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<test string>")
warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
-print "1. simple nesting"
+class ScopeTests(unittest.TestCase):
-def make_adder(x):
- def adder(y):
- return x + y
- return adder
+ def testSimpleNesting(self):
-inc = make_adder(1)
-plus10 = make_adder(10)
+ def make_adder(x):
+ def adder(y):
+ return x + y
+ return adder
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder(1)
+ plus10 = make_adder(10)
-print "2. extra nesting"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder2(x):
- def extra(): # check freevars passing through non-use scopes
- def adder(y):
- return x + y
- return adder
- return extra()
+ def testExtraNesting(self):
-inc = make_adder2(1)
-plus10 = make_adder2(10)
+ def make_adder2(x):
+ def extra(): # check freevars passing through non-use scopes
+ def adder(y):
+ return x + y
+ return adder
+ return extra()
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder2(1)
+ plus10 = make_adder2(10)
-print "3. simple nesting + rebinding"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder3(x):
- def adder(y):
- return x + y
- x = x + 1 # check tracking of assignment to x in defining scope
- return adder
+ def testSimpleAndRebinding(self):
-inc = make_adder3(0)
-plus10 = make_adder3(9)
+ def make_adder3(x):
+ def adder(y):
+ return x + y
+ x = x + 1 # check tracking of assignment to x in defining scope
+ return adder
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder3(0)
+ plus10 = make_adder3(9)
-print "4. nesting with global but no free"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder4(): # XXX add exta level of indirection
- def nest():
- def nest():
- def adder(y):
- return global_x + y # check that plain old globals work
- return adder
- return nest()
- return nest()
+ def testNestingGlobalNoFree(self):
-global_x = 1
-adder = make_adder4()
-vereq(adder(1), 2)
+ def make_adder4(): # XXX add exta level of indirection
+ def nest():
+ def nest():
+ def adder(y):
+ return global_x + y # check that plain old globals work
+ return adder
+ return nest()
+ return nest()
-global_x = 10
-vereq(adder(-2), 8)
+ global_x = 1
+ adder = make_adder4()
+ self.assertEqual(adder(1), 2)
-print "5. nesting through class"
+ global_x = 10
+ self.assertEqual(adder(-2), 8)
-def make_adder5(x):
- class Adder:
- def __call__(self, y):
- return x + y
- return Adder()
+ def testNestingThroughClass(self):
-inc = make_adder5(1)
-plus10 = make_adder5(10)
+ def make_adder5(x):
+ class Adder:
+ def __call__(self, y):
+ return x + y
+ return Adder()
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder5(1)
+ plus10 = make_adder5(10)
-print "6. nesting plus free ref to global"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder6(x):
- global global_nest_x
- def adder(y):
- return global_nest_x + y
- global_nest_x = x
- return adder
+ def testNestingPlusFreeRefToGlobal(self):
-inc = make_adder6(1)
-plus10 = make_adder6(10)
+ def make_adder6(x):
+ global global_nest_x
+ def adder(y):
+ return global_nest_x + y
+ global_nest_x = x
+ return adder
-vereq(inc(1), 11) # there's only one global
-vereq(plus10(-2), 8)
+ inc = make_adder6(1)
+ plus10 = make_adder6(10)
-print "7. nearest enclosing scope"
+ self.assertEqual(inc(1), 11) # there's only one global
+ self.assertEqual(plus10(-2), 8)
-def f(x):
- def g(y):
- x = 42 # check that this masks binding in f()
- def h(z):
- return x + z
- return h
- return g(2)
-
-test_func = f(10)
-vereq(test_func(5), 47)
-
-print "8. mixed freevars and cellvars"
-
-def identity(x):
- return x
-
-def f(x, y, z):
- def g(a, b, c):
- a = a + x # 3
- def h():
- # z * (4 + 9)
- # 3 * 13
- return identity(z * (b + y))
- y = c + z # 9
- return h
- return g
-
-g = f(1, 2, 3)
-h = g(2, 4, 6)
-vereq(h(), 39)
-
-print "9. free variable in method"
-
-def test():
- method_and_var = "var"
- class Test:
- def method_and_var(self):
- return "method"
- def test(self):
- return method_and_var
- def actual_global(self):
- return str("global")
- def str(self):
- return str(self)
- return Test()
-
-t = test()
-vereq(t.test(), "var")
-vereq(t.method_and_var(), "method")
-vereq(t.actual_global(), "global")
-
-method_and_var = "var"
-class Test:
- # this class is not nested, so the rules are different
- def method_and_var(self):
- return "method"
- def test(self):
- return method_and_var
- def actual_global(self):
- return str("global")
- def str(self):
- return str(self)
-
-t = Test()
-vereq(t.test(), "var")
-vereq(t.method_and_var(), "method")
-vereq(t.actual_global(), "global")
-
-print "10. recursion"
+ def testNearestEnclosingScope(self):
-def f(x):
- def fact(n):
- if n == 0:
- return 1
- else:
- return n * fact(n - 1)
- if x >= 0:
- return fact(x)
- else:
- raise ValueError, "x must be >= 0"
+ def f(x):
+ def g(y):
+ x = 42 # check that this masks binding in f()
+ def h(z):
+ return x + z
+ return h
+ return g(2)
-vereq(f(6), 720)
+ test_func = f(10)
+ self.assertEqual(test_func(5), 47)
+ def testMixedFreevarsAndCellvars(self):
-print "11. unoptimized namespaces"
+ def identity(x):
+ return x
-check_syntax("""\
+ def f(x, y, z):
+ def g(a, b, c):
+ a = a + x # 3
+ def h():
+ # z * (4 + 9)
+ # 3 * 13
+ return identity(z * (b + y))
+ y = c + z # 9
+ return h
+ return g
+
+ g = f(1, 2, 3)
+ h = g(2, 4, 6)
+ self.assertEqual(h(), 39)
+
+ def testFreeVarInMethod(self):
+
+ def test():
+ method_and_var = "var"
+ class Test:
+ def method_and_var(self):
+ return "method"
+ def test(self):
+ return method_and_var
+ def actual_global(self):
+ return str("global")
+ def str(self):
+ return str(self)
+ return Test()
+
+ t = test()
+ self.assertEqual(t.test(), "var")
+ self.assertEqual(t.method_and_var(), "method")
+ self.assertEqual(t.actual_global(), "global")
+
+ method_and_var = "var"
+ class Test:
+ # this class is not nested, so the rules are different
+ def method_and_var(self):
+ return "method"
+ def test(self):
+ return method_and_var
+ def actual_global(self):
+ return str("global")
+ def str(self):
+ return str(self)
+
+ t = Test()
+ self.assertEqual(t.test(), "var")
+ self.assertEqual(t.method_and_var(), "method")
+ self.assertEqual(t.actual_global(), "global")
+
+ def testRecursion(self):
+
+ def f(x):
+ def fact(n):
+ if n == 0:
+ return 1
+ else:
+ return n * fact(n - 1)
+ if x >= 0:
+ return fact(x)
+ else:
+ raise ValueError, "x must be >= 0"
+
+ self.assertEqual(f(6), 720)
+
+
+ def testUnoptimizedNamespaces(self):
+
+ check_syntax_error(self, """\
def unoptimized_clash1(strip):
def f(s):
from string import *
@@ -188,7 +192,7 @@ def unoptimized_clash1(strip):
return f
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def unoptimized_clash2():
from string import *
def f(s):
@@ -196,7 +200,7 @@ def unoptimized_clash2():
return f
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def unoptimized_clash2():
from string import *
def g():
@@ -205,23 +209,23 @@ def unoptimized_clash2():
return f
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def f(x):
def g():
return x
del x # can't del name
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def f():
def g():
- from string import *
- return strip # global or local?
+ from string import *
+ return strip # global or local?
""")
-# and verify a few cases that should work
+ # and verify a few cases that should work
-exec("""
+ exec("""
def noproblem1():
from string import *
f = lambda x:x
@@ -238,59 +242,60 @@ def noproblem3():
y = x
""")
-print "12. lambdas"
-
-f1 = lambda x: lambda y: x + y
-inc = f1(1)
-plus10 = f1(10)
-vereq(inc(1), 2)
-vereq(plus10(5), 15)
-
-f2 = lambda x: (lambda : lambda y: x + y)()
-inc = f2(1)
-plus10 = f2(10)
-vereq(inc(1), 2)
-vereq(plus10(5), 15)
-
-f3 = lambda x: lambda y: global_x + y
-global_x = 1
-inc = f3(None)
-vereq(inc(2), 3)
-
-f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
-g = f8(1, 2, 3)
-h = g(2, 4, 6)
-vereq(h(), 18)
-
-print "13. UnboundLocal"
-
-def errorInOuter():
- print y
- def inner():
- return y
- y = 1
-
-def errorInInner():
- def inner():
- return y
- inner()
- y = 1
-
-try:
- errorInOuter()
-except UnboundLocalError:
- pass
-else:
- raise TestFailed
+ def testLambdas(self):
+
+ f1 = lambda x: lambda y: x + y
+ inc = f1(1)
+ plus10 = f1(10)
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(5), 15)
+
+ f2 = lambda x: (lambda : lambda y: x + y)()
+ inc = f2(1)
+ plus10 = f2(10)
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(5), 15)
+
+ f3 = lambda x: lambda y: global_x + y
+ global_x = 1
+ inc = f3(None)
+ self.assertEqual(inc(2), 3)
+
+ f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
+ g = f8(1, 2, 3)
+ h = g(2, 4, 6)
+ self.assertEqual(h(), 18)
+
+ def testUnboundLocal(self):
+
+ def errorInOuter():
+ print y
+ def inner():
+ return y
+ y = 1
+
+ def errorInInner():
+ def inner():
+ return y
+ inner()
+ y = 1
+
+ try:
+ errorInOuter()
+ except UnboundLocalError:
+ pass
+ else:
+ self.fail()
-try:
- errorInInner()
-except NameError:
- pass
-else:
- raise TestFailed
+ try:
+ errorInInner()
+ except NameError:
+ pass
+ else:
+ self.fail()
-# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+ # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+ exec("""
global_x = 1
def f():
global_x += 1
@@ -299,34 +304,36 @@ try:
except UnboundLocalError:
pass
else:
- raise TestFailed, 'scope of global_x not correctly determined'
+ fail('scope of global_x not correctly determined')
+""", {'fail': self.fail})
-print "14. complex definitions"
+ def testComplexDefinitions(self):
-def makeReturner(*lst):
- def returner():
- return lst
- return returner
+ def makeReturner(*lst):
+ def returner():
+ return lst
+ return returner
-vereq(makeReturner(1,2,3)(), (1,2,3))
+ self.assertEqual(makeReturner(1,2,3)(), (1,2,3))
-def makeReturner2(**kwargs):
- def returner():
- return kwargs
- return returner
+ def makeReturner2(**kwargs):
+ def returner():
+ return kwargs
+ return returner
-vereq(makeReturner2(a=11)()['a'], 11)
+ self.assertEqual(makeReturner2(a=11)()['a'], 11)
-def makeAddPair((a, b)):
- def addPair((c, d)):
- return (a + c, b + d)
- return addPair
+ def makeAddPair((a, b)):
+ def addPair((c, d)):
+ return (a + c, b + d)
+ return addPair
-vereq(makeAddPair((1, 2))((100, 200)), (101,202))
+ self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202))
-print "15. scope of global statements"
+ def testScopeOfGlobalStmt(self):
# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
+ exec("""\
# I
x = 7
def f():
@@ -339,8 +346,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 7)
-vereq(x, 7)
+self.assertEqual(f(), 7)
+self.assertEqual(x, 7)
# II
x = 7
@@ -354,8 +361,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 2)
-vereq(x, 7)
+self.assertEqual(f(), 2)
+self.assertEqual(x, 7)
# III
x = 7
@@ -370,8 +377,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 2)
-vereq(x, 2)
+self.assertEqual(f(), 2)
+self.assertEqual(x, 2)
# IV
x = 7
@@ -386,8 +393,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 2)
-vereq(x, 2)
+self.assertEqual(f(), 2)
+self.assertEqual(x, 2)
# XXX what about global statements in class blocks?
# do they affect methods?
@@ -402,34 +409,36 @@ class Global:
return x
g = Global()
-vereq(g.get(), 13)
+self.assertEqual(g.get(), 13)
g.set(15)
-vereq(g.get(), 13)
+self.assertEqual(g.get(), 13)
+""")
-print "16. check leaks"
+ def testLeaks(self):
-class Foo:
- count = 0
+ class Foo:
+ count = 0
- def __init__(self):
- Foo.count += 1
+ def __init__(self):
+ Foo.count += 1
- def __del__(self):
- Foo.count -= 1
+ def __del__(self):
+ Foo.count -= 1
-def f1():
- x = Foo()
- def f2():
- return x
- f2()
+ def f1():
+ x = Foo()
+ def f2():
+ return x
+ f2()
-for i in range(100):
- f1()
+ for i in range(100):
+ f1()
-vereq(Foo.count, 0)
+ self.assertEqual(Foo.count, 0)
-print "17. class and global"
+ def testClassAndGlobal(self):
+ exec("""\
def test(x):
class Foo:
global x
@@ -438,9 +447,9 @@ def test(x):
return Foo()
x = 0
-vereq(test(6)(2), 8)
+self.assertEqual(test(6)(2), 8)
x = -1
-vereq(test(3)(2), 5)
+self.assertEqual(test(3)(2), 5)
looked_up_by_load_name = False
class X:
@@ -449,104 +458,106 @@ class X:
locals()['looked_up_by_load_name'] = True
passed = looked_up_by_load_name
-verify(X.passed)
+self.assert_(X.passed)
+""")
-print "18. verify that locals() works"
+ def testLocalsFunction(self):
-def f(x):
- def g(y):
- def h(z):
- return y + z
- w = x + y
- y += 3
- return locals()
- return g
+ def f(x):
+ def g(y):
+ def h(z):
+ return y + z
+ w = x + y
+ y += 3
+ return locals()
+ return g
-d = f(2)(4)
-verify('h' in d)
-del d['h']
-vereq(d, {'x': 2, 'y': 7, 'w': 6})
+ d = f(2)(4)
+ self.assert_('h' in d)
+ del d['h']
+ self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6})
-print "19. var is bound and free in class"
+ def testBoundAndFree(self):
+ # var is bound and free in class
-def f(x):
- class C:
- def m(self):
- return x
- a = x
- return C
+ def f(x):
+ class C:
+ def m(self):
+ return x
+ a = x
+ return C
-inst = f(3)()
-vereq(inst.a, inst.m())
+ inst = f(3)()
+ self.assertEqual(inst.a, inst.m())
-print "20. interaction with trace function"
+ def testInteractionWithTraceFunc(self):
-import sys
-def tracer(a,b,c):
- return tracer
+ import sys
+ def tracer(a,b,c):
+ return tracer
-def adaptgetter(name, klass, getter):
- kind, des = getter
- if kind == 1: # AV happens when stepping from this line to next
- if des == "":
- des = "_%s__%s" % (klass.__name__, name)
- return lambda obj: getattr(obj, des)
+ def adaptgetter(name, klass, getter):
+ kind, des = getter
+ if kind == 1: # AV happens when stepping from this line to next
+ if des == "":
+ des = "_%s__%s" % (klass.__name__, name)
+ return lambda obj: getattr(obj, des)
-class TestClass:
- pass
+ class TestClass:
+ pass
-sys.settrace(tracer)
-adaptgetter("foo", TestClass, (1, ""))
-sys.settrace(None)
+ sys.settrace(tracer)
+ adaptgetter("foo", TestClass, (1, ""))
+ sys.settrace(None)
-try: sys.settrace()
-except TypeError: pass
-else: raise TestFailed, 'sys.settrace() did not raise TypeError'
+ self.assertRaises(TypeError, sys.settrace)
-print "20. eval and exec with free variables"
+ def testEvalExecFreeVars(self):
-def f(x):
- return lambda: x + 1
+ def f(x):
+ return lambda: x + 1
-g = f(3)
-try:
- eval(g.func_code)
-except TypeError:
- pass
-else:
- print "eval() should have failed, because code contained free vars"
+ g = f(3)
+ self.assertRaises(TypeError, eval, g.func_code)
-try:
- exec(g.func_code)
-except TypeError:
- pass
-else:
- print "exec should have failed, because code contained free vars"
+ try:
+ exec(g.func_code, {})
+ except TypeError:
+ pass
+ else:
+ self.fail("exec should have failed, because code contained free vars")
-print "21. list comprehension with local variables"
+ def testListCompLocalVars(self):
-try:
- print bad
-except NameError:
- pass
-else:
- print "bad should not be defined"
+ try:
+ print bad
+ except NameError:
+ pass
+ else:
+ print "bad should not be defined"
-def x():
- [bad for s in 'a b' for bad in s.split()]
+ def x():
+ [bad for s in 'a b' for bad in s.split()]
-x()
-try:
- print bad
-except NameError:
- pass
+ x()
+ try:
+ print bad
+ except NameError:
+ pass
-print "22. eval with free variables"
+ def testEvalFreeVars(self):
-def f(x):
- def g():
- x
- eval("x + 1")
- return g
+ def f(x):
+ def g():
+ x
+ eval("x + 1")
+ return g
+
+ f(4)()
+
+
+def test_main():
+ run_unittest(ScopeTests)
-f(4)()
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index 03621a6..a4830d4 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -298,6 +298,17 @@ class TestSet(TestJointOps):
self.assert_(self.thetype(self.word) not in s)
self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
+ def test_remove_keyerror_unpacking(self):
+ # bug: www.python.org/sf/1576657
+ for v1 in ['Q', (1,)]:
+ try:
+ self.s.remove(v1)
+ except KeyError, e:
+ v2 = e.args[0]
+ self.assertEqual(v1, v2)
+ else:
+ self.fail()
+
def test_discard(self):
self.s.discard('a')
self.assert_('a' not in self.s)
diff --git a/Lib/test/test_sgmllib.py b/Lib/test/test_sgmllib.py
index 28a21a4..b698636 100644
--- a/Lib/test/test_sgmllib.py
+++ b/Lib/test/test_sgmllib.py
@@ -286,21 +286,6 @@ DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
('codepoint', 'convert', 42),
])
- def test_attr_values_quoted_markup(self):
- """Multi-line and markup in attribute values"""
- self.check_events("""<a title='foo\n<br>bar'>text</a>""",
- [("starttag", "a", [("title", "foo\n<br>bar")]),
- ("data", "text"),
- ("endtag", "a")])
- self.check_events("""<a title='less < than'>text</a>""",
- [("starttag", "a", [("title", "less < than")]),
- ("data", "text"),
- ("endtag", "a")])
- self.check_events("""<a title='greater > than'>text</a>""",
- [("starttag", "a", [("title", "greater > than")]),
- ("data", "text"),
- ("endtag", "a")])
-
def test_attr_funky_names(self):
self.check_events("""<a a.b='v' c:d=v e-f=v>""", [
("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
@@ -376,6 +361,19 @@ DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
('decl', 'DOCTYPE doc [<!ATTLIST doc attr (a | b) >]'),
])
+ def test_read_chunks(self):
+ # SF bug #1541697, this caused sgml parser to hang
+ # Just verify this code doesn't cause a hang.
+ CHUNK = 1024 # increasing this to 8212 makes the problem go away
+
+ f = open(test_support.findfile('sgml_input.html'))
+ fp = sgmllib.SGMLParser()
+ while 1:
+ data = f.read(CHUNK)
+ fp.feed(data)
+ if len(data) != CHUNK:
+ break
+
# XXX These tests have been disabled by prefixing their names with
# an underscore. The first two exercise outstanding bugs in the
# sgmllib module, and the third exhibits questionable behavior
diff --git a/Lib/test/test_sha.py b/Lib/test/test_sha.py
index c438cc6..ea224e4 100644
--- a/Lib/test/test_sha.py
+++ b/Lib/test/test_sha.py
@@ -11,9 +11,23 @@ from test import test_support
class SHATestCase(unittest.TestCase):
def check(self, data, digest):
- computed = sha.new(data).hexdigest()
+ # Check digest matches the expected value
+ obj = sha.new(data)
+ computed = obj.hexdigest()
self.assert_(computed == digest)
+ # Verify that the value doesn't change between two consecutive
+ # digest operations.
+ computed_again = obj.hexdigest()
+ self.assert_(computed == computed_again)
+
+ # Check hexdigest() output matches digest()'s output
+ digest = obj.digest()
+ hexd = ""
+ for c in digest:
+ hexd += '%02x' % ord(c)
+ self.assert_(computed == hexd)
+
def test_case_1(self):
self.check("abc",
"a9993e364706816aba3e25717850c26c9cd0d89d")
@@ -26,6 +40,9 @@ class SHATestCase(unittest.TestCase):
self.check("a" * 1000000,
"34aa973cd4c4daa4f61eeb2bdbad27316534016f")
+ def test_case_4(self):
+ self.check(chr(0xAA) * 80,
+ '4ca0ef38f1794b28a8f8ee110ee79d48ce13be25')
def test_main():
test_support.run_unittest(SHATestCase)
diff --git a/Lib/test/test_structmembers.py b/Lib/test/test_structmembers.py
new file mode 100644
index 0000000..93dd2ac
--- /dev/null
+++ b/Lib/test/test_structmembers.py
@@ -0,0 +1,80 @@
+from _testcapi import test_structmembersType, \
+ CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
+ SHRT_MAX, SHRT_MIN, USHRT_MAX, \
+ INT_MAX, INT_MIN, UINT_MAX, \
+ LONG_MAX, LONG_MIN, ULONG_MAX
+
+import warnings, exceptions, unittest, test.test_warnings
+from test import test_support
+
+ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
+
+class ReadWriteTests(unittest.TestCase):
+ def test_types(self):
+ ts.T_BYTE=CHAR_MAX
+ self.assertEquals(ts.T_BYTE, CHAR_MAX)
+ ts.T_BYTE=CHAR_MIN
+ self.assertEquals(ts.T_BYTE, CHAR_MIN)
+ ts.T_UBYTE=UCHAR_MAX
+ self.assertEquals(ts.T_UBYTE, UCHAR_MAX)
+
+ ts.T_SHORT=SHRT_MAX
+ self.assertEquals(ts.T_SHORT, SHRT_MAX)
+ ts.T_SHORT=SHRT_MIN
+ self.assertEquals(ts.T_SHORT, SHRT_MIN)
+ ts.T_USHORT=USHRT_MAX
+ self.assertEquals(ts.T_USHORT, USHRT_MAX)
+
+ ts.T_INT=INT_MAX
+ self.assertEquals(ts.T_INT, INT_MAX)
+ ts.T_INT=INT_MIN
+ self.assertEquals(ts.T_INT, INT_MIN)
+ ts.T_UINT=UINT_MAX
+ self.assertEquals(ts.T_UINT, UINT_MAX)
+
+ ts.T_LONG=LONG_MAX
+ self.assertEquals(ts.T_LONG, LONG_MAX)
+ ts.T_LONG=LONG_MIN
+ self.assertEquals(ts.T_LONG, LONG_MIN)
+ ts.T_ULONG=ULONG_MAX
+ self.assertEquals(ts.T_ULONG, ULONG_MAX)
+
+class TestWarnings(test.test_warnings.TestModule):
+ def has_warned(self):
+ self.assertEqual(test.test_warnings.msg.category,
+ exceptions.RuntimeWarning.__name__)
+
+ def test_byte_max(self):
+ ts.T_BYTE=CHAR_MAX+1
+ self.has_warned()
+
+ def test_byte_min(self):
+ ts.T_BYTE=CHAR_MIN-1
+ self.has_warned()
+
+ def test_ubyte_max(self):
+ ts.T_UBYTE=UCHAR_MAX+1
+ self.has_warned()
+
+ def test_short_max(self):
+ ts.T_SHORT=SHRT_MAX+1
+ self.has_warned()
+
+ def test_short_min(self):
+ ts.T_SHORT=SHRT_MIN-1
+ self.has_warned()
+
+ def test_ushort_max(self):
+ ts.T_USHORT=USHRT_MAX+1
+ self.has_warned()
+
+
+
+def test_main(verbose=None):
+ test_support.run_unittest(
+ ReadWriteTests,
+ TestWarnings
+ )
+
+if __name__ == "__main__":
+ test_main(verbose=True)
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 8c8ac40..64f8d40 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -234,6 +234,12 @@ class ProcessTestCase(unittest.TestCase):
stripped = remove_stderr_debug_decorations(output)
self.assertEqual(stripped, "appleorange")
+ def test_stdout_filedes_of_stdout(self):
+ # stdout is set to 1 (#1531862).
+ cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
+ rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
+ self.assertEquals(rc, 2)
+
def test_cwd(self):
tmpdir = os.getenv("TEMP", "/tmp")
# We cannot use os.path.realpath to canonicalize the path,
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index d260fc5..2829c55 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -244,13 +244,13 @@ def sortdict(dict):
withcommas = ", ".join(reprpairs)
return "{%s}" % withcommas
-def check_syntax(statement):
+def check_syntax_error(testcase, statement):
try:
- compile(statement, '<string>', 'exec')
+ compile(statement, '<test string>', 'exec')
except SyntaxError:
pass
else:
- print 'Missing SyntaxError: "%s"' % statement
+ testcase.fail('Missing SyntaxError: "%s"' % statement)
def open_urlresource(url):
import urllib, urlparse
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index acb3f10..a0eaac6 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -235,6 +235,138 @@ SyntaxError: assignment to None (<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)
+
+
+Test continue in finally in weird combinations.
+
+continue in for loop under finally shouuld be ok.
+
+ >>> def test():
+ ... try:
+ ... pass
+ ... finally:
+ ... for abc in range(10):
+ ... continue
+ ... print abc
+ >>> test()
+ 9
+
+Start simple, a continue in a finally should not be allowed.
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[36]>, line 6)
+
+This is essentially a continue in a finally which should not be allowed.
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... continue
+ ... except:
+ ... pass
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[37]>, line 7)
+
+ >>> def foo():
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[38]>, line 5)
+
+ >>> def foo():
+ ... for a in ():
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[39]>, line 6)
+
+ >>> def foo():
+ ... for a in ():
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... continue
+ ... finally:
+ ... pass
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[40]>, line 7)
+
+ >>> def foo():
+ ... for a in ():
+ ... try: pass
+ ... finally:
+ ... try:
+ ... pass
+ ... except:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[41]>, line 8)
+
+There is one test for a break that is not in a loop. The compiler
+uses a single data structure to keep track of try-finally and loops,
+so we need to be sure that a break is actually inside a loop. If it
+isn't, there should be a syntax error.
+
+ >>> try:
+ ... print 1
+ ... break
+ ... print 2
+ ... finally:
+ ... print 3
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'break' outside loop (<doctest test.test_syntax[42]>, line 3)
+
+This should probably raise a better error than a SystemError (or none at all).
+In 2.5 there was a missing exception and an assert was triggered in a debug
+build. The number of blocks must be greater than CO_MAXBLOCKS. SF #1565514
+
+ >>> while 1:
+ ... while 2:
+ ... while 3:
+ ... while 4:
+ ... while 5:
+ ... while 6:
+ ... while 8:
+ ... while 9:
+ ... while 10:
+ ... while 11:
+ ... while 12:
+ ... while 13:
+ ... while 14:
+ ... while 15:
+ ... while 16:
+ ... while 17:
+ ... while 18:
+ ... while 19:
+ ... while 20:
+ ... while 21:
+ ... while 22:
+ ... break
+ Traceback (most recent call last):
+ ...
+ SystemError: too many statically nested blocks
+
"""
import re
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index a47afa4..0cebb29 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -280,6 +280,32 @@ class WriteTest(BaseTest):
else:
self.dst.addfile(tarinfo, f)
+
+class Write100Test(BaseTest):
+ # The name field in a tar header stores strings of at most 100 chars.
+ # If a string is shorter than 100 chars it has to be padded with '\0',
+ # which implies that a string of exactly 100 chars is stored without
+ # a trailing '\0'.
+
+ def setUp(self):
+ self.name = "01234567890123456789012345678901234567890123456789"
+ self.name += "01234567890123456789012345678901234567890123456789"
+
+ self.tar = tarfile.open(tmpname(), "w")
+ t = tarfile.TarInfo(self.name)
+ self.tar.addfile(t)
+ self.tar.close()
+
+ self.tar = tarfile.open(tmpname())
+
+ def tearDown(self):
+ self.tar.close()
+
+ def test(self):
+ self.assertEqual(self.tar.getnames()[0], self.name,
+ "failed to store 100 char filename")
+
+
class WriteSize0Test(BaseTest):
mode = 'w'
@@ -362,13 +388,6 @@ class WriteGNULongTest(unittest.TestCase):
is tested as well.
"""
- def setUp(self):
- self.tar = tarfile.open(tmpname(), "w")
- self.tar.posix = False
-
- def tearDown(self):
- self.tar.close()
-
def _length(self, s):
blocks, remainder = divmod(len(s) + 1, 512)
if remainder:
@@ -397,12 +416,23 @@ class WriteGNULongTest(unittest.TestCase):
tarinfo.linkname = link
tarinfo.type = tarfile.LNKTYPE
- self.tar.addfile(tarinfo)
+ tar = tarfile.open(tmpname(), "w")
+ tar.posix = False
+ tar.addfile(tarinfo)
v1 = self._calc_size(name, link)
- v2 = self.tar.offset
+ v2 = tar.offset
self.assertEqual(v1, v2, "GNU longname/longlink creation failed")
+ tar.close()
+
+ tar = tarfile.open(tmpname())
+ member = tar.next()
+ self.failIf(member is None, "unable to read longname member")
+ self.assert_(tarinfo.name == member.name and \
+ tarinfo.linkname == member.linkname, \
+ "unable to read longname member")
+
def test_longname_1023(self):
self._test(("longnam/" * 127) + "longnam")
@@ -623,6 +653,7 @@ def test_main():
ReadAsteriskTest,
ReadStreamAsteriskTest,
WriteTest,
+ Write100Test,
WriteSize0Test,
WriteStreamTest,
WriteGNULongTest,
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index aeaa77e..2047a63 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -27,7 +27,7 @@ has_spawnl = hasattr(os, 'spawnl')
# number of files that can be opened at one time (see ulimit -n)
if sys.platform == 'mac':
TEST_FILES = 32
-elif sys.platform == 'openbsd3':
+elif sys.platform in ('openbsd3', 'openbsd4'):
TEST_FILES = 48
else:
TEST_FILES = 100
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index 4fd7834..18129da 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -102,15 +102,19 @@ class TimeTestCase(unittest.TestCase):
self.assertEquals(expected, result)
def test_strptime(self):
+ # Should be able to go round-trip from strftime to strptime without
+ # throwing an exception.
tt = time.gmtime(self.t)
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
'j', 'm', 'M', 'p', 'S',
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
- format = ' %' + directive
+ format = '%' + directive
+ strf_output = time.strftime(format, tt)
try:
- time.strptime(time.strftime(format, tt), format)
+ time.strptime(strf_output, format)
except ValueError:
- self.fail('conversion specifier: %r failed.' % format)
+ self.fail("conversion specifier %r failed with '%s' input." %
+ (format, strf_output))
def test_asctime(self):
time.asctime(time.gmtime(self.t))
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
index b064967..be6c18d 100644
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -1,9 +1,93 @@
-import os, glob, random
+"""Tests for the tokenize module.
+
+The tests were originally written in the old Python style, where the
+test output was compared to a golden file. This docstring represents
+the first steps towards rewriting the entire test as a doctest.
+
+The tests can be really simple. Given a small fragment of source
+code, print out a table with the tokens. The ENDMARK is omitted for
+brevity.
+
+>>> dump_tokens("1 + 1")
+NUMBER '1' (1, 0) (1, 1)
+OP '+' (1, 2) (1, 3)
+NUMBER '1' (1, 4) (1, 5)
+
+A comment generates a token here, unlike in the parser module. The
+comment token is followed by an NL or a NEWLINE token, depending on
+whether the line contains the completion of a statement.
+
+>>> dump_tokens("if False:\\n"
+... " # NL\\n"
+... " True = False # NEWLINE\\n")
+NAME 'if' (1, 0) (1, 2)
+NAME 'False' (1, 3) (1, 8)
+OP ':' (1, 8) (1, 9)
+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)
+OP '=' (3, 9) (3, 10)
+NAME 'False' (3, 11) (3, 16)
+COMMENT '# NEWLINE' (3, 17) (3, 26)
+NEWLINE '\\n' (3, 26) (3, 27)
+DEDENT '' (4, 0) (4, 0)
+
+
+There will be a bunch more tests of specific source patterns.
+
+The tokenize module also defines an untokenize function that should
+regenerate the original program text from the tokens.
+
+There are some standard formatting practices that are easy to get right.
+
+>>> roundtrip("if x == 1:\\n"
+... " print x\\n")
+if x == 1:
+ print x
+
+Some people use different formatting conventions, which makes
+untokenize a little trickier. Note that this test involves trailing
+whitespace after the colon. Note that we use hex escapes to make the
+two trailing blanks apparent in the expected output.
+
+>>> roundtrip("if x == 1 : \\n"
+... " print x\\n")
+if x == 1 :\x20\x20
+ print x
+
+Comments need to go in the right place.
+
+>>> roundtrip("if x == 1:\\n"
+... " # A comment by itself.\\n"
+... " print x # Comment here, too.\\n"
+... " # Another comment.\\n"
+... "after_if = True\\n")
+if x == 1:
+ # A comment by itself.
+ print x # Comment here, too.
+ # Another comment.
+after_if = True
+
+>>> roundtrip("if (x # The comments need to go in the right place\\n"
+... " == 1):\\n"
+... " print 'x == 1'\\n")
+if (x # The comments need to go in the right place
+ == 1):
+ print 'x == 1'
+
+"""
+
+import os, glob, random, time, sys
from cStringIO import StringIO
from test.test_support import (verbose, findfile, is_resource_enabled,
TestFailed)
-from tokenize import (tokenize, generate_tokens, untokenize,
- NUMBER, NAME, OP, STRING)
+from tokenize import (tokenize, generate_tokens, untokenize, tok_name,
+ ENDMARKER, NUMBER, NAME, OP, STRING, COMMENT)
+
+# How much time in seconds can pass before we print a 'Still working' message.
+_PRINT_WORKING_MSG_INTERVAL = 5 * 60
# Test roundtrip for `untokenize`. `f` is a file path. The source code in f
# is tokenized, converted back to source code via tokenize.untokenize(),
@@ -24,6 +108,23 @@ def test_roundtrip(f):
if t1 != t2:
raise TestFailed("untokenize() roundtrip failed for %r" % f)
+def dump_tokens(s):
+ """Print out the tokens in s in a table format.
+
+ The ENDMARKER is omitted.
+ """
+ f = StringIO(s)
+ for type, token, start, end, line in generate_tokens(f.readline):
+ if type == ENDMARKER:
+ break
+ type = tok_name[type]
+ print "%(type)-10.10s %(token)-13.13r %(start)s %(end)s" % locals()
+
+def roundtrip(s):
+ f = StringIO(s)
+ source = untokenize(generate_tokens(f.readline))
+ print source,
+
# This is an example from the docs, set up as a doctest.
def decistmt(s):
"""Substitute Decimals for floats in a string of statements.
@@ -66,6 +167,8 @@ def test_main():
if verbose:
print 'starting...'
+ next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+
# This displays the tokenization of tokenize_tests.py to stdout, and
# regrtest.py checks that this equals the expected output (in the
# test/output/ directory).
@@ -85,6 +188,12 @@ def test_main():
testfiles = random.sample(testfiles, 10)
for f in testfiles:
+ # Print still working message since this test can be really slow
+ if next_time <= time.time():
+ next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+ print >>sys.__stdout__, ' test_main still working, be patient...'
+ sys.__stdout__.flush()
+
test_roundtrip(f)
# Test detecton of IndentationError.
@@ -105,7 +214,7 @@ def foo():
# Run the doctests in this module.
from test import test_tokenize # i.e., this module
from test.test_support import run_doctest
- run_doctest(test_tokenize)
+ run_doctest(test_tokenize, verbose)
if verbose:
print 'finished'
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 9ba1dca..48c5d19 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -122,6 +122,10 @@ def test():
X.__name__,
str_value))
+ def test_without_exception(self):
+ err = traceback.format_exception_only(None, None)
+ self.assertEqual(err, ['None\n'])
+
def test_main():
run_unittest(TracebackCases)
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index f0bdfde..8d26914 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -1,285 +1,271 @@
# Python test set -- part 6, built-in types
-from test.test_support import *
-
-print '6. Built-in types'
-
-print '6.1 Truth value testing'
-if None: raise TestFailed, 'None is true instead of false'
-if 0: raise TestFailed, '0 is true instead of false'
-if 0L: raise TestFailed, '0L is true instead of false'
-if 0.0: raise TestFailed, '0.0 is true instead of false'
-if '': raise TestFailed, '\'\' is true instead of false'
-if not 1: raise TestFailed, '1 is false instead of true'
-if not 1L: raise TestFailed, '1L is false instead of true'
-if not 1.0: raise TestFailed, '1.0 is false instead of true'
-if not 'x': raise TestFailed, '\'x\' is false instead of true'
-if not {'x': 1}: raise TestFailed, '{\'x\': 1} is false instead of true'
-def f(): pass
-class C: pass
+from test.test_support import run_unittest, have_unicode
+import unittest
import sys
-x = C()
-if not f: raise TestFailed, 'f is false instead of true'
-if not C: raise TestFailed, 'C is false instead of true'
-if not sys: raise TestFailed, 'sys is false instead of true'
-if not x: raise TestFailed, 'x is false instead of true'
-
-print '6.2 Boolean operations'
-if 0 or 0: raise TestFailed, '0 or 0 is true instead of false'
-if 1 and 1: pass
-else: raise TestFailed, '1 and 1 is false instead of true'
-if not 1: raise TestFailed, 'not 1 is true instead of false'
-
-print '6.3 Comparisons'
-if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
-else: raise TestFailed, 'int comparisons failed'
-if 0L < 1L <= 1L == 1L >= 1L > 0L != 1L: pass
-else: raise TestFailed, 'long int comparisons failed'
-if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
-else: raise TestFailed, 'float comparisons failed'
-if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
-else: raise TestFailed, 'string comparisons failed'
-if None is None: pass
-else: raise TestFailed, 'identity test failed'
-
-try: float('')
-except ValueError: pass
-else: raise TestFailed, "float('') didn't raise ValueError"
-
-try: float('5\0')
-except ValueError: pass
-else: raise TestFailed, "float('5\0') didn't raise ValueError"
-
-try: 5.0 / 0.0
-except ZeroDivisionError: pass
-else: raise TestFailed, "5.0 / 0.0 didn't raise ZeroDivisionError"
-
-try: 5.0 // 0.0
-except ZeroDivisionError: pass
-else: raise TestFailed, "5.0 // 0.0 didn't raise ZeroDivisionError"
-
-try: 5.0 % 0.0
-except ZeroDivisionError: pass
-else: raise TestFailed, "5.0 % 0.0 didn't raise ZeroDivisionError"
-
-try: 5 / 0L
-except ZeroDivisionError: pass
-else: raise TestFailed, "5 / 0L didn't raise ZeroDivisionError"
-
-try: 5 // 0L
-except ZeroDivisionError: pass
-else: raise TestFailed, "5 // 0L didn't raise ZeroDivisionError"
-
-try: 5 % 0L
-except ZeroDivisionError: pass
-else: raise TestFailed, "5 % 0L didn't raise ZeroDivisionError"
-
-print '6.4 Numeric types (mostly conversions)'
-if 0 != 0L or 0 != 0.0 or 0L != 0.0: raise TestFailed, 'mixed comparisons'
-if 1 != 1L or 1 != 1.0 or 1L != 1.0: raise TestFailed, 'mixed comparisons'
-if -1 != -1L or -1 != -1.0 or -1L != -1.0:
- raise TestFailed, 'int/long/float value not equal'
-# calling built-in types without argument must return 0
-if int() != 0: raise TestFailed, 'int() does not return 0'
-if long() != 0L: raise TestFailed, 'long() does not return 0L'
-if float() != 0.0: raise TestFailed, 'float() does not return 0.0'
-if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
-else: raise TestFailed, 'int() does not round properly'
-if long(1.9) == 1L == long(1.1) and long(-1.1) == -1L == long(-1.9): pass
-else: raise TestFailed, 'long() does not round properly'
-if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
-else: raise TestFailed, 'float() does not work properly'
-print '6.4.1 32-bit integers'
-# Ensure the first 256 integers are shared
-a = 256
-b = 128*2
-if a is not b: raise TestFailed, '256 is not shared'
-if 12 + 24 != 36: raise TestFailed, 'int op'
-if 12 + (-24) != -12: raise TestFailed, 'int op'
-if (-12) + 24 != 12: raise TestFailed, 'int op'
-if (-12) + (-24) != -36: raise TestFailed, 'int op'
-if not 12 < 24: raise TestFailed, 'int op'
-if not -24 < -12: raise TestFailed, 'int op'
-# Test for a particular bug in integer multiply
-xsize, ysize, zsize = 238, 356, 4
-if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
- raise TestFailed, 'int mul commutativity'
-# And another.
-m = -sys.maxint - 1
-for divisor in 1, 2, 4, 8, 16, 32:
- j = m // divisor
- prod = divisor * j
- if prod != m:
- raise TestFailed, "%r * %r == %r != %r" % (divisor, j, prod, m)
- if type(prod) is not int:
- raise TestFailed, ("expected type(prod) to be int, not %r" %
- type(prod))
-# Check for expected * overflow to long.
-for divisor in 1, 2, 4, 8, 16, 32:
- j = m // divisor - 1
- prod = divisor * j
- if type(prod) is not long:
- raise TestFailed, ("expected type(%r) to be long, not %r" %
- (prod, type(prod)))
-# Check for expected * overflow to long.
-m = sys.maxint
-for divisor in 1, 2, 4, 8, 16, 32:
- j = m // divisor + 1
- prod = divisor * j
- if type(prod) is not long:
- raise TestFailed, ("expected type(%r) to be long, not %r" %
- (prod, type(prod)))
-
-print '6.4.2 Long integers'
-if 12L + 24L != 36L: raise TestFailed, 'long op'
-if 12L + (-24L) != -12L: raise TestFailed, 'long op'
-if (-12L) + 24L != 12L: raise TestFailed, 'long op'
-if (-12L) + (-24L) != -36L: raise TestFailed, 'long op'
-if not 12L < 24L: raise TestFailed, 'long op'
-if not -24L < -12L: raise TestFailed, 'long op'
-x = sys.maxint
-if int(long(x)) != x: raise TestFailed, 'long op'
-try: y = int(long(x)+1L)
-except OverflowError: raise TestFailed, 'long op'
-if not isinstance(y, long): raise TestFailed, 'long op'
-x = -x
-if int(long(x)) != x: raise TestFailed, 'long op'
-x = x-1
-if int(long(x)) != x: raise TestFailed, 'long op'
-try: y = int(long(x)-1L)
-except OverflowError: raise TestFailed, 'long op'
-if not isinstance(y, long): raise TestFailed, 'long op'
-
-try: 5 << -5
-except ValueError: pass
-else: raise TestFailed, 'int negative shift <<'
-
-try: 5L << -5L
-except ValueError: pass
-else: raise TestFailed, 'long negative shift <<'
-
-try: 5 >> -5
-except ValueError: pass
-else: raise TestFailed, 'int negative shift >>'
-
-try: 5L >> -5L
-except ValueError: pass
-else: raise TestFailed, 'long negative shift >>'
-
-print '6.4.3 Floating point numbers'
-if 12.0 + 24.0 != 36.0: raise TestFailed, 'float op'
-if 12.0 + (-24.0) != -12.0: raise TestFailed, 'float op'
-if (-12.0) + 24.0 != 12.0: raise TestFailed, 'float op'
-if (-12.0) + (-24.0) != -36.0: raise TestFailed, 'float op'
-if not 12.0 < 24.0: raise TestFailed, 'float op'
-if not -24.0 < -12.0: raise TestFailed, 'float op'
-
-print '6.5 Sequence types'
-
-print '6.5.1 Strings'
-if len('') != 0: raise TestFailed, 'len(\'\')'
-if len('a') != 1: raise TestFailed, 'len(\'a\')'
-if len('abcdef') != 6: raise TestFailed, 'len(\'abcdef\')'
-if 'xyz' + 'abcde' != 'xyzabcde': raise TestFailed, 'string concatenation'
-if 'xyz'*3 != 'xyzxyzxyz': raise TestFailed, 'string repetition *3'
-if 0*'abcde' != '': raise TestFailed, 'string repetition 0*'
-if min('abc') != 'a' or max('abc') != 'c': raise TestFailed, 'min/max string'
-if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
-else: raise TestFailed, 'in/not in string'
-x = 'x'*103
-if '%s!'%x != x+'!': raise TestFailed, 'nasty string formatting bug'
-
-#extended slices for strings
-a = '0123456789'
-vereq(a[::], a)
-vereq(a[::2], '02468')
-vereq(a[1::2], '13579')
-vereq(a[::-1],'9876543210')
-vereq(a[::-2], '97531')
-vereq(a[3::-2], '31')
-vereq(a[-100:100:], a)
-vereq(a[100:-100:-1], a[::-1])
-vereq(a[-100L:100L:2L], '02468')
-
-if have_unicode:
- a = unicode('0123456789', 'ascii')
- vereq(a[::], a)
- vereq(a[::2], unicode('02468', 'ascii'))
- vereq(a[1::2], unicode('13579', 'ascii'))
- vereq(a[::-1], unicode('9876543210', 'ascii'))
- vereq(a[::-2], unicode('97531', 'ascii'))
- vereq(a[3::-2], unicode('31', 'ascii'))
- vereq(a[-100:100:], a)
- vereq(a[100:-100:-1], a[::-1])
- vereq(a[-100L:100L:2L], unicode('02468', 'ascii'))
-
-
-print '6.5.2 Tuples [see test_tuple.py]'
-
-print '6.5.3 Lists [see test_list.py]'
-
-print '6.6 Mappings == Dictionaries [see test_dict.py]'
-
-
-try: type(1, 2)
-except TypeError: pass
-else: raise TestFailed, 'type(), w/2 args expected TypeError'
-
-try: type(1, 2, 3, 4)
-except TypeError: pass
-else: raise TestFailed, 'type(), w/4 args expected TypeError'
-
-print 'Buffers'
-try: buffer('asdf', -1)
-except ValueError: pass
-else: raise TestFailed, "buffer('asdf', -1) should raise ValueError"
-
-try: buffer(None)
-except TypeError: pass
-else: raise TestFailed, "buffer(None) should raise TypeError"
-
-a = buffer('asdf')
-hash(a)
-b = a * 5
-if a == b:
- raise TestFailed, 'buffers should not be equal'
-if str(b) != ('asdf' * 5):
- raise TestFailed, 'repeated buffer has wrong content'
-if str(a * 0) != '':
- raise TestFailed, 'repeated buffer zero times has wrong content'
-if str(a + buffer('def')) != 'asdfdef':
- raise TestFailed, 'concatenation of buffers yields wrong content'
-if str(buffer(a)) != 'asdf':
- raise TestFailed, 'composing buffers failed'
-if str(buffer(a, 2)) != 'df':
- raise TestFailed, 'specifying buffer offset failed'
-if str(buffer(a, 0, 2)) != 'as':
- raise TestFailed, 'specifying buffer size failed'
-if str(buffer(a, 1, 2)) != 'sd':
- raise TestFailed, 'specifying buffer offset and size failed'
-try: buffer(buffer('asdf', 1), -1)
-except ValueError: pass
-else: raise TestFailed, "buffer(buffer('asdf', 1), -1) should raise ValueError"
-if str(buffer(buffer('asdf', 0, 2), 0)) != 'as':
- raise TestFailed, 'composing length-specified buffer failed'
-if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as':
- raise TestFailed, 'composing length-specified buffer failed'
-if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as':
- raise TestFailed, 'composing length-specified buffer failed'
-if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's':
- raise TestFailed, 'composing length-specified buffer failed'
-
-try: a[1] = 'g'
-except TypeError: pass
-else: raise TestFailed, "buffer assignment should raise TypeError"
-
-try: a[0:1] = 'g'
-except TypeError: pass
-else: raise TestFailed, "buffer slice assignment should raise TypeError"
-
-# array.array() returns an object that does not implement a char buffer,
-# something which int() uses for conversion.
-import array
-try: int(buffer(array.array('c')))
-except TypeError :pass
-else: raise TestFailed, "char buffer (at C level) not working"
+
+class TypesTests(unittest.TestCase):
+
+ def test_truth_values(self):
+ if None: self.fail('None is true instead of false')
+ if 0: self.fail('0 is true instead of false')
+ if 0L: self.fail('0L is true instead of false')
+ if 0.0: self.fail('0.0 is true instead of false')
+ if '': self.fail('\'\' is true instead of false')
+ if not 1: self.fail('1 is false instead of true')
+ if not 1L: self.fail('1L is false instead of true')
+ if not 1.0: self.fail('1.0 is false instead of true')
+ if not 'x': self.fail('\'x\' is false instead of true')
+ if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true')
+ def f(): pass
+ class C: pass
+ import sys
+ x = C()
+ if not f: self.fail('f is false instead of true')
+ if not C: self.fail('C is false instead of true')
+ if not sys: self.fail('sys is false instead of true')
+ if not x: self.fail('x is false instead of true')
+
+ def test_boolean_ops(self):
+ if 0 or 0: self.fail('0 or 0 is true instead of false')
+ if 1 and 1: pass
+ else: self.fail('1 and 1 is false instead of true')
+ if not 1: self.fail('not 1 is true instead of false')
+
+ def test_comparisons(self):
+ if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
+ else: self.fail('int comparisons failed')
+ if 0L < 1L <= 1L == 1L >= 1L > 0L != 1L: pass
+ else: self.fail('long int comparisons failed')
+ if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
+ else: self.fail('float comparisons failed')
+ if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
+ else: self.fail('string comparisons failed')
+ if None is None: pass
+ else: self.fail('identity test failed')
+
+ def test_float_constructor(self):
+ self.assertRaises(ValueError, float, '')
+ self.assertRaises(ValueError, float, '5\0')
+
+ def test_zero_division(self):
+ try: 5.0 / 0.0
+ except ZeroDivisionError: pass
+ else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
+
+ try: 5.0 // 0.0
+ except ZeroDivisionError: pass
+ else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
+
+ try: 5.0 % 0.0
+ except ZeroDivisionError: pass
+ else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
+
+ try: 5 / 0L
+ except ZeroDivisionError: pass
+ else: self.fail("5 / 0L didn't raise ZeroDivisionError")
+
+ try: 5 // 0L
+ except ZeroDivisionError: pass
+ else: self.fail("5 // 0L didn't raise ZeroDivisionError")
+
+ try: 5 % 0L
+ except ZeroDivisionError: pass
+ else: self.fail("5 % 0L didn't raise ZeroDivisionError")
+
+ def test_numeric_types(self):
+ if 0 != 0L or 0 != 0.0 or 0L != 0.0: self.fail('mixed comparisons')
+ if 1 != 1L or 1 != 1.0 or 1L != 1.0: self.fail('mixed comparisons')
+ if -1 != -1L or -1 != -1.0 or -1L != -1.0:
+ self.fail('int/long/float value not equal')
+ # calling built-in types without argument must return 0
+ if int() != 0: self.fail('int() does not return 0')
+ if long() != 0L: self.fail('long() does not return 0L')
+ if float() != 0.0: self.fail('float() does not return 0.0')
+ if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
+ else: self.fail('int() does not round properly')
+ if long(1.9) == 1L == long(1.1) and long(-1.1) == -1L == long(-1.9): pass
+ else: self.fail('long() does not round properly')
+ if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
+ else: self.fail('float() does not work properly')
+
+ def test_normal_integers(self):
+ # Ensure the first 256 integers are shared
+ a = 256
+ b = 128*2
+ if a is not b: self.fail('256 is not shared')
+ if 12 + 24 != 36: self.fail('int op')
+ if 12 + (-24) != -12: self.fail('int op')
+ if (-12) + 24 != 12: self.fail('int op')
+ if (-12) + (-24) != -36: self.fail('int op')
+ if not 12 < 24: self.fail('int op')
+ if not -24 < -12: self.fail('int op')
+ # Test for a particular bug in integer multiply
+ xsize, ysize, zsize = 238, 356, 4
+ if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
+ self.fail('int mul commutativity')
+ # And another.
+ m = -sys.maxint - 1
+ for divisor in 1, 2, 4, 8, 16, 32:
+ j = m // divisor
+ prod = divisor * j
+ if prod != m:
+ self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
+ if type(prod) is not int:
+ self.fail("expected type(prod) to be int, not %r" %
+ type(prod))
+ # Check for expected * overflow to long.
+ for divisor in 1, 2, 4, 8, 16, 32:
+ j = m // divisor - 1
+ prod = divisor * j
+ if type(prod) is not long:
+ self.fail("expected type(%r) to be long, not %r" %
+ (prod, type(prod)))
+ # Check for expected * overflow to long.
+ m = sys.maxint
+ for divisor in 1, 2, 4, 8, 16, 32:
+ j = m // divisor + 1
+ prod = divisor * j
+ if type(prod) is not long:
+ self.fail("expected type(%r) to be long, not %r" %
+ (prod, type(prod)))
+
+ def test_long_integers(self):
+ if 12L + 24L != 36L: self.fail('long op')
+ if 12L + (-24L) != -12L: self.fail('long op')
+ if (-12L) + 24L != 12L: self.fail('long op')
+ if (-12L) + (-24L) != -36L: self.fail('long op')
+ if not 12L < 24L: self.fail('long op')
+ if not -24L < -12L: self.fail('long op')
+ x = sys.maxint
+ if int(long(x)) != x: self.fail('long op')
+ try: y = int(long(x)+1L)
+ except OverflowError: self.fail('long op')
+ if not isinstance(y, long): self.fail('long op')
+ x = -x
+ if int(long(x)) != x: self.fail('long op')
+ x = x-1
+ if int(long(x)) != x: self.fail('long op')
+ try: y = int(long(x)-1L)
+ except OverflowError: self.fail('long op')
+ if not isinstance(y, long): self.fail('long op')
+
+ try: 5 << -5
+ except ValueError: pass
+ else: self.fail('int negative shift <<')
+
+ try: 5L << -5L
+ except ValueError: pass
+ else: self.fail('long negative shift <<')
+
+ try: 5 >> -5
+ except ValueError: pass
+ else: self.fail('int negative shift >>')
+
+ try: 5L >> -5L
+ except ValueError: pass
+ else: self.fail('long negative shift >>')
+
+ def test_floats(self):
+ if 12.0 + 24.0 != 36.0: self.fail('float op')
+ if 12.0 + (-24.0) != -12.0: self.fail('float op')
+ if (-12.0) + 24.0 != 12.0: self.fail('float op')
+ if (-12.0) + (-24.0) != -36.0: self.fail('float op')
+ if not 12.0 < 24.0: self.fail('float op')
+ if not -24.0 < -12.0: self.fail('float op')
+
+ def test_strings(self):
+ if len('') != 0: self.fail('len(\'\')')
+ if len('a') != 1: self.fail('len(\'a\')')
+ if len('abcdef') != 6: self.fail('len(\'abcdef\')')
+ if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
+ if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
+ if 0*'abcde' != '': self.fail('string repetition 0*')
+ if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
+ if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
+ else: self.fail('in/not in string')
+ x = 'x'*103
+ if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
+
+ #extended slices for strings
+ a = '0123456789'
+ self.assertEqual(a[::], a)
+ self.assertEqual(a[::2], '02468')
+ self.assertEqual(a[1::2], '13579')
+ self.assertEqual(a[::-1],'9876543210')
+ self.assertEqual(a[::-2], '97531')
+ self.assertEqual(a[3::-2], '31')
+ self.assertEqual(a[-100:100:], a)
+ self.assertEqual(a[100:-100:-1], a[::-1])
+ self.assertEqual(a[-100L:100L:2L], '02468')
+
+ if have_unicode:
+ a = unicode('0123456789', 'ascii')
+ self.assertEqual(a[::], a)
+ self.assertEqual(a[::2], unicode('02468', 'ascii'))
+ self.assertEqual(a[1::2], unicode('13579', 'ascii'))
+ self.assertEqual(a[::-1], unicode('9876543210', 'ascii'))
+ self.assertEqual(a[::-2], unicode('97531', 'ascii'))
+ self.assertEqual(a[3::-2], unicode('31', 'ascii'))
+ self.assertEqual(a[-100:100:], a)
+ self.assertEqual(a[100:-100:-1], a[::-1])
+ self.assertEqual(a[-100L:100L:2L], unicode('02468', 'ascii'))
+
+
+ def test_type_function(self):
+ self.assertRaises(TypeError, type, 1, 2)
+ self.assertRaises(TypeError, type, 1, 2, 3, 4)
+
+ def test_buffers(self):
+ self.assertRaises(ValueError, buffer, 'asdf', -1)
+ self.assertRaises(TypeError, buffer, None)
+
+ a = buffer('asdf')
+ hash(a)
+ b = a * 5
+ if a == b:
+ self.fail('buffers should not be equal')
+ if str(b) != ('asdf' * 5):
+ self.fail('repeated buffer has wrong content')
+ if str(a * 0) != '':
+ self.fail('repeated buffer zero times has wrong content')
+ if str(a + buffer('def')) != 'asdfdef':
+ self.fail('concatenation of buffers yields wrong content')
+ if str(buffer(a)) != 'asdf':
+ self.fail('composing buffers failed')
+ if str(buffer(a, 2)) != 'df':
+ self.fail('specifying buffer offset failed')
+ if str(buffer(a, 0, 2)) != 'as':
+ self.fail('specifying buffer size failed')
+ if str(buffer(a, 1, 2)) != 'sd':
+ self.fail('specifying buffer offset and size failed')
+ self.assertRaises(ValueError, buffer, buffer('asdf', 1), -1)
+ if str(buffer(buffer('asdf', 0, 2), 0)) != 'as':
+ self.fail('composing length-specified buffer failed')
+ if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as':
+ self.fail('composing length-specified buffer failed')
+ if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as':
+ self.fail('composing length-specified buffer failed')
+ if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's':
+ self.fail('composing length-specified buffer failed')
+
+ try: a[1] = 'g'
+ except TypeError: pass
+ else: self.fail("buffer assignment should raise TypeError")
+
+ try: a[0:1] = 'g'
+ except TypeError: pass
+ else: self.fail("buffer slice assignment should raise TypeError")
+
+ # array.array() returns an object that does not implement a char buffer,
+ # something which int() uses for conversion.
+ import array
+ try: int(buffer(array.array('c')))
+ except TypeError: pass
+ else: self.fail("char buffer (at C level) not working")
+
+def test_main():
+ run_unittest(TypesTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 517ecfd..38ff9ac 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -92,6 +92,9 @@ class UnicodeTest(
"\\xfe\\xff'")
testrepr = repr(u''.join(map(unichr, xrange(256))))
self.assertEqual(testrepr, latin1repr)
+ # Test repr works on wide unicode escapes without overflow.
+ self.assertEqual(repr(u"\U00010000" * 39 + u"\uffff" * 4096),
+ repr(u"\U00010000" * 39 + u"\uffff" * 4096))
def test_iterators(self):
# Make sure unicode objects have an __iter__ method
diff --git a/Lib/test/test_xdrlib.py b/Lib/test/test_xdrlib.py
index e9517c5..8fc88a5 100644
--- a/Lib/test/test_xdrlib.py
+++ b/Lib/test/test_xdrlib.py
@@ -1,3 +1,56 @@
+from test import test_support
+import unittest
+
import xdrlib
-xdrlib._test()
+class XDRTest(unittest.TestCase):
+
+ def test_xdr(self):
+ p = xdrlib.Packer()
+
+ s = 'hello world'
+ a = ['what', 'is', 'hapnin', 'doctor']
+
+ p.pack_int(42)
+ p.pack_uint(9)
+ p.pack_bool(True)
+ p.pack_bool(False)
+ p.pack_uhyper(45L)
+ p.pack_float(1.9)
+ p.pack_double(1.9)
+ p.pack_string(s)
+ p.pack_list(range(5), p.pack_uint)
+ p.pack_array(a, p.pack_string)
+
+ # now verify
+ data = p.get_buffer()
+ up = xdrlib.Unpacker(data)
+
+ self.assertEqual(up.get_position(), 0)
+
+ self.assertEqual(up.unpack_int(), 42)
+ self.assertEqual(up.unpack_uint(), 9)
+ self.assert_(up.unpack_bool() is True)
+
+ # remember position
+ pos = up.get_position()
+ self.assert_(up.unpack_bool() is False)
+
+ # rewind and unpack again
+ up.set_position(pos)
+ self.assert_(up.unpack_bool() is False)
+
+ self.assertEqual(up.unpack_uhyper(), 45L)
+ self.assertAlmostEqual(up.unpack_float(), 1.9)
+ self.assertAlmostEqual(up.unpack_double(), 1.9)
+ self.assertEqual(up.unpack_string(), s)
+ self.assertEqual(up.unpack_list(up.unpack_uint), range(5))
+ self.assertEqual(up.unpack_array(up.unpack_string), a)
+ up.done()
+ self.assertRaises(EOFError, up.unpack_uint)
+
+def test_main():
+ test_support.run_unittest(XDRTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
index 64d8fe8..ccc1b60 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -86,6 +86,15 @@ class XMLRPCTestCase(unittest.TestCase):
s = xmlrpclib.dumps((new_d,), methodresponse=True)
self.assert_(isinstance(s, str))
+ def test_newstyle_class(self):
+ class T(object):
+ pass
+ t = T()
+ t.x = 100
+ t.y = "Hello"
+ ((t2,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((t,)))
+ self.assertEquals(t2, t.__dict__)
+
def test_dump_big_long(self):
self.assertRaises(OverflowError, xmlrpclib.dumps, (2L**99,))
diff --git a/Lib/tokenize.py b/Lib/tokenize.py
index 5d65267..1253822 100644
--- a/Lib/tokenize.py
+++ b/Lib/tokenize.py
@@ -24,7 +24,7 @@ each time a new token is found."""
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
__credits__ = \
- 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
+ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro, Raymond Hettinger'
import string, re
from token import *
@@ -159,14 +159,73 @@ def tokenize_loop(readline, tokeneater):
for token_info in generate_tokens(readline):
tokeneater(*token_info)
+class Untokenizer:
+
+ def __init__(self):
+ self.tokens = []
+ self.prev_row = 1
+ self.prev_col = 0
+
+ def add_whitespace(self, start):
+ row, col = start
+ assert row <= self.prev_row
+ col_offset = col - self.prev_col
+ if col_offset:
+ self.tokens.append(" " * col_offset)
+
+ def untokenize(self, iterable):
+ for t in iterable:
+ if len(t) == 2:
+ self.compat(t, iterable)
+ break
+ tok_type, token, start, end, line = t
+ self.add_whitespace(start)
+ self.tokens.append(token)
+ self.prev_row, self.prev_col = end
+ if tok_type in (NEWLINE, NL):
+ self.prev_row += 1
+ self.prev_col = 0
+ return "".join(self.tokens)
+
+ def compat(self, token, iterable):
+ startline = False
+ indents = []
+ toks_append = self.tokens.append
+ toknum, tokval = token
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+ if toknum in (NEWLINE, NL):
+ startline = True
+ for tok in iterable:
+ toknum, tokval = tok[:2]
+
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+
+ if toknum == INDENT:
+ indents.append(tokval)
+ continue
+ elif toknum == DEDENT:
+ indents.pop()
+ continue
+ elif toknum in (NEWLINE, NL):
+ startline = True
+ elif startline and indents:
+ toks_append(indents[-1])
+ startline = False
+ toks_append(tokval)
def untokenize(iterable):
"""Transform tokens back into Python source code.
Each element returned by the iterable must be a token sequence
- with at least two elements, a token number and token value.
+ with at least two elements, a token number and token value. If
+ only two tokens are passed, the resulting output is poor.
+
+ Round-trip invariant for full input:
+ Untokenized source will match input source exactly
- Round-trip invariant:
+ Round-trip invariant for limited intput:
# Output text will tokenize the back to the input
t1 = [tok[:2] for tok in generate_tokens(f.readline)]
newcode = untokenize(t1)
@@ -174,31 +233,8 @@ def untokenize(iterable):
t2 = [tok[:2] for tokin generate_tokens(readline)]
assert t1 == t2
"""
-
- startline = False
- indents = []
- toks = []
- toks_append = toks.append
- for tok in iterable:
- toknum, tokval = tok[:2]
-
- if toknum in (NAME, NUMBER):
- tokval += ' '
-
- if toknum == INDENT:
- indents.append(tokval)
- continue
- elif toknum == DEDENT:
- indents.pop()
- continue
- elif toknum in (NEWLINE, COMMENT, NL):
- startline = True
- elif startline and indents:
- toks_append(indents[-1])
- startline = False
- toks_append(tokval)
- return ''.join(toks)
-
+ ut = Untokenizer()
+ return ut.untokenize(iterable)
def generate_tokens(readline):
"""
@@ -237,7 +273,7 @@ def generate_tokens(readline):
if endmatch:
pos = end = endmatch.end(0)
yield (STRING, contstr + line[:end],
- strstart, (lnum, end), contline + line)
+ strstart, (lnum, end), contline + line)
contstr, needcont = '', 0
contline = None
elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
@@ -263,7 +299,15 @@ def generate_tokens(readline):
if pos == max: break
if line[pos] in '#\r\n': # skip comments or blank lines
- yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+ if line[pos] == '#':
+ comment_token = line[pos:].rstrip('\r\n')
+ nl_pos = pos + len(comment_token)
+ yield (COMMENT, comment_token,
+ (lnum, pos), (lnum, pos + len(comment_token)), line)
+ yield (NL, line[nl_pos:],
+ (lnum, nl_pos), (lnum, len(line)), line)
+ else:
+ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
(lnum, pos), (lnum, len(line)), line)
continue
@@ -294,9 +338,10 @@ def generate_tokens(readline):
(initial == '.' and token != '.'): # ordinary number
yield (NUMBER, token, spos, epos, line)
elif initial in '\r\n':
- yield (parenlev > 0 and NL or NEWLINE,
- token, spos, epos, line)
+ yield (NL if parenlev > 0 else NEWLINE,
+ token, spos, epos, line)
elif initial == '#':
+ assert not token.endswith("\n")
yield (COMMENT, token, spos, epos, line)
elif token in triple_quoted:
endprog = endprogs[token]
diff --git a/Lib/traceback.py b/Lib/traceback.py
index eb2fdf6..e395ad7 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -162,6 +162,11 @@ def format_exception_only(etype, value):
"""
+ # Gracefully handle (the way Python 2.4 and earlier did) the case of
+ # being called with (None, None).
+ if etype is None:
+ return [_format_final_exc_line(etype, value)]
+
stype = etype.__name__
smod = etype.__module__
if smod not in ("exceptions", "__main__", "__builtin__"):
diff --git a/Lib/urllib.py b/Lib/urllib.py
index e01f421..90f7aa0 100644
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -302,13 +302,13 @@ class URLopener:
if proxy_passwd:
import base64
- proxy_auth = base64.encodestring(proxy_passwd).strip()
+ proxy_auth = base64.b64encode(proxy_passwd).strip()
else:
proxy_auth = None
if user_passwd:
import base64
- auth = base64.encodestring(user_passwd).strip()
+ auth = base64.b64encode(user_passwd).strip()
else:
auth = None
h = httplib.HTTP(host)
@@ -387,12 +387,12 @@ class URLopener:
if not host: raise IOError, ('https error', 'no host given')
if proxy_passwd:
import base64
- proxy_auth = base64.encodestring(proxy_passwd).strip()
+ proxy_auth = base64.b64encode(proxy_passwd).strip()
else:
proxy_auth = None
if user_passwd:
import base64
- auth = base64.encodestring(user_passwd).strip()
+ auth = base64.b64encode(user_passwd).strip()
else:
auth = None
h = httplib.HTTPS(host, 0,
diff --git a/Lib/urllib2.py b/Lib/urllib2.py
index 1e19f33..a880e64 100644
--- a/Lib/urllib2.py
+++ b/Lib/urllib2.py
@@ -674,7 +674,7 @@ class ProxyHandler(BaseHandler):
proxy_type = orig_type
if user and password:
user_pass = '%s:%s' % (unquote(user), unquote(password))
- creds = base64.encodestring(user_pass).strip()
+ creds = base64.b64encode(user_pass).strip()
req.add_header('Proxy-authorization', 'Basic ' + creds)
hostport = unquote(hostport)
req.set_proxy(hostport, proxy_type)
@@ -798,7 +798,7 @@ class AbstractBasicAuthHandler:
user, pw = self.passwd.find_user_password(realm, host)
if pw is not None:
raw = "%s:%s" % (user, pw)
- auth = 'Basic %s' % base64.encodestring(raw).strip()
+ auth = 'Basic %s' % base64.b64encode(raw).strip()
if req.headers.get(self.auth_header, None) == auth:
return None
req.add_header(self.auth_header, auth)
diff --git a/Lib/uu.py b/Lib/uu.py
index 3ccedb0..da89f72 100755
--- a/Lib/uu.py
+++ b/Lib/uu.py
@@ -114,6 +114,7 @@ def decode(in_file, out_file=None, mode=None, quiet=0):
#
# Open the output file
#
+ opened = False
if out_file == '-':
out_file = sys.stdout
elif isinstance(out_file, basestring):
@@ -123,6 +124,7 @@ def decode(in_file, out_file=None, mode=None, quiet=0):
except AttributeError:
pass
out_file = fp
+ opened = True
#
# Main decoding loop
#
@@ -140,6 +142,8 @@ def decode(in_file, out_file=None, mode=None, quiet=0):
s = in_file.readline()
if not s:
raise Error('Truncated input file')
+ if opened:
+ out_file.close()
def test():
"""uuencode/uudecode main program"""
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index 9fd1615..0d5f44f 100644
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -165,7 +165,10 @@ class GenericBrowser(BaseBrowser):
cmdline = [self.name] + [arg.replace("%s", url)
for arg in self.args]
try:
- p = subprocess.Popen(cmdline, close_fds=True)
+ if sys.platform[:3] == 'win':
+ p = subprocess.Popen(cmdline)
+ else:
+ p = subprocess.Popen(cmdline, close_fds=True)
return not p.wait()
except OSError:
return False
@@ -178,11 +181,14 @@ class BackgroundBrowser(GenericBrowser):
def open(self, url, new=0, autoraise=1):
cmdline = [self.name] + [arg.replace("%s", url)
for arg in self.args]
- setsid = getattr(os, 'setsid', None)
- if not setsid:
- setsid = getattr(os, 'setpgrp', None)
try:
- p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid)
+ if sys.platform[:3] == 'win':
+ p = subprocess.Popen(cmdline)
+ else:
+ setsid = getattr(os, 'setsid', None)
+ if not setsid:
+ setsid = getattr(os, 'setpgrp', None)
+ p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid)
return (p.poll() is None)
except OSError:
return False
@@ -441,7 +447,7 @@ def register_X_browsers():
# if successful, register it
if retncode is None and commd:
- register("gnome", None, BackgroundBrowser(commd))
+ register("gnome", None, BackgroundBrowser(commd.split()))
# First, the Mozilla/Netscape browsers
for browser in ("mozilla-firefox", "firefox",
diff --git a/Lib/xdrlib.py b/Lib/xdrlib.py
index b349eb9..796dfaf 100644
--- a/Lib/xdrlib.py
+++ b/Lib/xdrlib.py
@@ -227,61 +227,3 @@ class Unpacker:
def unpack_array(self, unpack_item):
n = self.unpack_uint()
return self.unpack_farray(n, unpack_item)
-
-
-# test suite
-def _test():
- p = Packer()
- packtest = [
- (p.pack_uint, (9,)),
- (p.pack_bool, (True,)),
- (p.pack_bool, (False,)),
- (p.pack_uhyper, (45L,)),
- (p.pack_float, (1.9,)),
- (p.pack_double, (1.9,)),
- (p.pack_string, ('hello world',)),
- (p.pack_list, (range(5), p.pack_uint)),
- (p.pack_array, (['what', 'is', 'hapnin', 'doctor'], p.pack_string)),
- ]
- succeedlist = [1] * len(packtest)
- count = 0
- for method, args in packtest:
- print 'pack test', count,
- try:
- method(*args)
- print 'succeeded'
- except ConversionError, var:
- print 'ConversionError:', var.msg
- succeedlist[count] = 0
- count = count + 1
- data = p.get_buffer()
- # now verify
- up = Unpacker(data)
- unpacktest = [
- (up.unpack_uint, (), lambda x: x == 9),
- (up.unpack_bool, (), lambda x: x is True),
- (up.unpack_bool, (), lambda x: x is False),
- (up.unpack_uhyper, (), lambda x: x == 45L),
- (up.unpack_float, (), lambda x: 1.89 < x < 1.91),
- (up.unpack_double, (), lambda x: 1.89 < x < 1.91),
- (up.unpack_string, (), lambda x: x == 'hello world'),
- (up.unpack_list, (up.unpack_uint,), lambda x: x == range(5)),
- (up.unpack_array, (up.unpack_string,),
- lambda x: x == ['what', 'is', 'hapnin', 'doctor']),
- ]
- count = 0
- for method, args, pred in unpacktest:
- print 'unpack test', count,
- try:
- if succeedlist[count]:
- x = method(*args)
- print pred(x) and 'succeeded' or 'failed', ':', x
- else:
- print 'skipping'
- except ConversionError, var:
- print 'ConversionError:', var.msg
- count = count + 1
-
-
-if __name__ == '__main__':
- _test()
diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py
index 72866f1..da3d396 100644
--- a/Lib/xmlrpclib.py
+++ b/Lib/xmlrpclib.py
@@ -593,9 +593,21 @@ class Marshaller:
try:
f = self.dispatch[type(value)]
except KeyError:
- raise TypeError, "cannot marshal %s objects" % type(value)
- else:
- f(self, value, write)
+ # check if this object can be marshalled as a structure
+ try:
+ value.__dict__
+ except:
+ raise TypeError, "cannot marshal %s objects" % type(value)
+ # check if this class is a sub-class of a basic type,
+ # because we don't know how to marshal these types
+ # (e.g. a string sub-class)
+ for type_ in type(value).__mro__:
+ if type_ in self.dispatch.keys():
+ raise TypeError, "cannot marshal %s objects" % type(value)
+ # XXX(twouters): using "_arbitrary_instance" as key as a quick-fix
+ # for the p3yk merge, this should probably be fixed more neatly.
+ f = self.dispatch["_arbitrary_instance"]
+ f(self, value, write)
def dump_nil (self, value, write):
if not self.allow_none:
@@ -713,6 +725,9 @@ class Marshaller:
self.dump_struct(value.__dict__, write)
dispatch[DateTime] = dump_instance
dispatch[Binary] = dump_instance
+ # XXX(twouters): using "_arbitrary_instance" as key as a quick-fix
+ # for the p3yk merge, this should probably be fixed more neatly.
+ dispatch["_arbitrary_instance"] = dump_instance
##
# XML-RPC unmarshaller.