diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/collections.py | 5 | ||||
-rw-r--r-- | Lib/decimal.py | 14 | ||||
-rw-r--r-- | Lib/test/test_decimal.py | 17 | ||||
-rw-r--r-- | Lib/test/test_pyexpat.py | 128 | ||||
-rw-r--r-- | Lib/test/test_socket.py | 2 | ||||
-rw-r--r-- | Lib/test/test_winreg.py | 45 |
6 files changed, 184 insertions, 27 deletions
diff --git a/Lib/collections.py b/Lib/collections.py index 2f0d038..e1e9d11 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -34,7 +34,8 @@ def namedtuple(typename, field_names, verbose=False): """ - # Parse and validate the field names + # Parse and validate the field names. Validation serves two purposes, + # generating informative error messages and preventing template injection attacks. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas field_names = tuple(field_names) @@ -129,7 +130,7 @@ if __name__ == '__main__': 'Point class with optimized _make() and _replace() without error-checking' _make = classmethod(tuple.__new__) def _replace(self, _map=map, **kwds): - return self._make(_map(kwds.pop, ('x', 'y'), self)) + return self._make(_map(kwds.get, ('x', 'y'), self)) print(Point(11, 22)._replace(x=100)) diff --git a/Lib/decimal.py b/Lib/decimal.py index 54e8cb4..1f5ff12 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -809,8 +809,10 @@ class Decimal(_numbers.Real, _numbers.Inexact): def __hash__(self): """x.__hash__() <==> hash(x)""" # Decimal integers must hash the same as the ints - # Non-integer decimals are normalized and hashed as strings - # Normalization assures that hash(100E-1) == hash(10) + # + # The hash of a nonspecial noninteger Decimal must depend only + # on the value of that Decimal, and not on its representation. + # For example: hash(Decimal("100E-1")) == hash(Decimal("10")). if self._is_special: if self._isnan(): raise TypeError('Cannot hash a NaN value.') @@ -826,7 +828,13 @@ class Decimal(_numbers.Real, _numbers.Inexact): # 2**64-1. So we can replace hash((-1)**s*c*10**e) with # hash((-1)**s*c*pow(10, e, 2**64-1). return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1)) - return hash(str(self.normalize())) + # The value of a nonzero nonspecial Decimal instance is + # faithfully represented by the triple consisting of its sign, + # its adjusted exponent, and its coefficient with trailing + # zeros removed. + return hash((self._sign, + self._exp+len(self._int), + self._int.rstrip('0'))) def as_tuple(self): """Represents the number as a triple tuple. diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 3c64e64..0dd7f00 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -971,6 +971,23 @@ class DecimalUsabilityTest(unittest.TestCase): self.assert_(hash(Decimal('Inf'))) self.assert_(hash(Decimal('-Inf'))) + # check that the value of the hash doesn't depend on the + # current context (issue #1757) + c = getcontext() + old_precision = c.prec + x = Decimal("123456789.1") + + c.prec = 6 + h1 = hash(x) + c.prec = 10 + h2 = hash(x) + c.prec = 16 + h3 = hash(x) + + self.assertEqual(h1, h2) + self.assertEqual(h1, h3) + c.prec = old_precision + def test_min_and_max_methods(self): d1 = Decimal('15.32') diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index cb4e6eb..9fda72d 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -2,6 +2,7 @@ # handler, are obscure and unhelpful. from io import BytesIO +import sys import unittest import pyexpat @@ -385,6 +386,130 @@ class sf1296433Test(unittest.TestCase): self.assertRaises(Exception, parser.Parse, xml) +class ChardataBufferTest(unittest.TestCase): + """ + test setting of chardata buffer size + """ + + def test_1025_bytes(self): + self.assertEquals(self.small_buffer_test(1025), 2) + + def test_1000_bytes(self): + self.assertEquals(self.small_buffer_test(1000), 1) + + def test_wrong_size(self): + parser = expat.ParserCreate() + parser.buffer_text = 1 + def f(size): + parser.buffer_size = size + + self.assertRaises(ValueError, f, -1) + self.assertRaises(ValueError, f, 0) + + def test_unchanged_size(self): + xml1 = ("<?xml version='1.0' encoding='iso8859'?><s>%s" % ('a' * 512)) + xml2 = 'a'*512 + '</s>' + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_size = 512 + parser.buffer_text = 1 + + # Feed 512 bytes of character data: the handler should be called + # once. + self.n = 0 + parser.Parse(xml1) + self.assertEquals(self.n, 1) + + # Reassign to buffer_size, but assign the same size. + parser.buffer_size = parser.buffer_size + self.assertEquals(self.n, 1) + + # Try parsing rest of the document + parser.Parse(xml2) + self.assertEquals(self.n, 2) + + + def test_disabling_buffer(self): + xml1 = "<?xml version='1.0' encoding='iso8859'?><a>%s" % ('a' * 512) + xml2 = ('b' * 1024) + xml3 = "%s</a>" % ('c' * 1024) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_text = 1 + parser.buffer_size = 1024 + self.assertEquals(parser.buffer_size, 1024) + + # Parse one chunk of XML + self.n = 0 + parser.Parse(xml1, 0) + self.assertEquals(parser.buffer_size, 1024) + self.assertEquals(self.n, 1) + + # Turn off buffering and parse the next chunk. + parser.buffer_text = 0 + self.assertFalse(parser.buffer_text) + self.assertEquals(parser.buffer_size, 1024) + for i in range(10): + parser.Parse(xml2, 0) + self.assertEquals(self.n, 11) + + parser.buffer_text = 1 + self.assertTrue(parser.buffer_text) + self.assertEquals(parser.buffer_size, 1024) + parser.Parse(xml3, 1) + self.assertEquals(self.n, 12) + + + + def make_document(self, bytes): + return ("<?xml version='1.0'?><tag>" + bytes * 'a' + '</tag>') + + def counting_handler(self, text): + self.n += 1 + + def small_buffer_test(self, buffer_len): + xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * buffer_len) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_size = 1024 + parser.buffer_text = 1 + + self.n = 0 + parser.Parse(xml) + return self.n + + def test_change_size_1(self): + xml1 = "<?xml version='1.0' encoding='iso8859'?><a><s>%s" % ('a' * 1024) + xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_text = 1 + parser.buffer_size = 1024 + self.assertEquals(parser.buffer_size, 1024) + + self.n = 0 + parser.Parse(xml1, 0) + parser.buffer_size *= 2 + self.assertEquals(parser.buffer_size, 2048) + parser.Parse(xml2, 1) + self.assertEquals(self.n, 2) + + def test_change_size_2(self): + xml1 = "<?xml version='1.0' encoding='iso8859'?><a>a<s>%s" % ('a' * 1023) + xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025) + parser = expat.ParserCreate() + parser.CharacterDataHandler = self.counting_handler + parser.buffer_text = 1 + parser.buffer_size = 2048 + self.assertEquals(parser.buffer_size, 2048) + + self.n=0 + parser.Parse(xml1, 0) + parser.buffer_size = parser.buffer_size // 2 + self.assertEquals(parser.buffer_size, 1024) + parser.Parse(xml2, 1) + self.assertEquals(self.n, 4) + def test_main(): run_unittest(SetAttributeTest, @@ -394,7 +519,8 @@ def test_main(): BufferTextTest, HandlerExceptionTest, PositionTest, - sf1296433Test) + sf1296433Test, + ChardataBufferTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index bc31620..d474206 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1133,7 +1133,7 @@ def isTipcAvailable(): for line in f: if line.startswith("tipc "): return True - if test_support.debug: + if test_support.verbose: print("TIPC module is not loaded, please 'sudo modprobe tipc'") return False diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 7b1baf8..3f73c74 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -73,26 +73,26 @@ class WinregTests(unittest.TestCase): key = OpenKey(root_key, test_key_name) # Read the sub-keys - sub_key = OpenKey(key, subkeystr) - # Check I can enumerate over the values. - index = 0 - while 1: - try: - data = EnumValue(sub_key, index) - except EnvironmentError: - break - self.assertEquals(data in test_data, True, - "Didn't read back the correct test data") - index = index + 1 - self.assertEquals(index, len(test_data), - "Didn't read the correct number of items") - # Check I can directly access each item - for value_name, value_data, value_type in test_data: - read_val, read_typ = QueryValueEx(sub_key, value_name) - self.assertEquals(read_val, value_data, - "Could not directly read the value") - self.assertEquals(read_typ, value_type, - "Could not directly read the value") + with OpenKey(key, "sub_key") as sub_key: + # Check I can enumerate over the values. + index = 0 + while 1: + try: + data = EnumValue(sub_key, index) + except EnvironmentError: + break + self.assertEquals(data in test_data, True, + "Didn't read back the correct test data") + index = index + 1 + self.assertEquals(index, len(test_data), + "Didn't read the correct number of items") + # Check I can directly access each item + for value_name, value_data, value_type in test_data: + read_val, read_typ = QueryValueEx(sub_key, value_name) + self.assertEquals(read_val, value_data, + "Could not directly read the value") + self.assertEquals(read_typ, value_type, + "Could not directly read the value") sub_key.Close() # Enumerate our main key. read_val = EnumKey(key, 0) @@ -155,6 +155,11 @@ class WinregTests(unittest.TestCase): remote_key = ConnectRegistry(self.remote_name, HKEY_CURRENT_USER) self.TestAll(remote_key) + def testExpandEnvironmentStrings(self): + r = ExpandEnvironmentStrings("%windir%\\test") + self.assertEqual(type(r), str) + self.assertEqual(r, os.environ["windir"] + "\\test") + def test_main(): test_support.run_unittest(WinregTests) |