From python-checkins at python.org Sun Nov 1 00:19:53 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 31 Oct 2009 23:19:53 -0000 Subject: [Python-checkins] r76001 - python/trunk/Lib/test/test_mailbox.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 00:19:52 2009 New Revision: 76001 Log: Use richer assertions in test_mailbox (for better failure messages). Modified: python/trunk/Lib/test/test_mailbox.py Modified: python/trunk/Lib/test/test_mailbox.py ============================================================================== --- python/trunk/Lib/test/test_mailbox.py (original) +++ python/trunk/Lib/test/test_mailbox.py Sun Nov 1 00:19:52 2009 @@ -22,17 +22,17 @@ def _check_sample(self, msg): # Inspect a mailbox.Message representation of the sample message - self.assertTrue(isinstance(msg, email.message.Message)) - self.assertTrue(isinstance(msg, mailbox.Message)) + self.assertIsInstance(msg, email.message.Message) + self.assertIsInstance(msg, mailbox.Message) for key, value in _sample_headers.iteritems(): - self.assertTrue(value in msg.get_all(key)) + self.assertIn(value, msg.get_all(key)) self.assertTrue(msg.is_multipart()) - self.assertTrue(len(msg.get_payload()) == len(_sample_payloads)) + self.assertEqual(len(msg.get_payload()), len(_sample_payloads)) for i, payload in enumerate(_sample_payloads): part = msg.get_payload(i) - self.assertTrue(isinstance(part, email.message.Message)) - self.assertTrue(not isinstance(part, mailbox.Message)) - self.assertTrue(part.get_payload() == payload) + self.assertIsInstance(part, email.message.Message) + self.assertNotIsInstance(part, mailbox.Message) + self.assertEqual(part.get_payload(), payload) def _delete_recursively(self, target): # Delete a file or delete a directory recursively @@ -65,16 +65,16 @@ # Add copies of a sample message keys = [] keys.append(self._box.add(self._template % 0)) - self.assertTrue(len(self._box) == 1) + self.assertEqual(len(self._box), 1) keys.append(self._box.add(mailbox.Message(_sample_message))) - self.assertTrue(len(self._box) == 2) + self.assertEqual(len(self._box), 2) keys.append(self._box.add(email.message_from_string(_sample_message))) - self.assertTrue(len(self._box) == 3) + self.assertEqual(len(self._box), 3) keys.append(self._box.add(StringIO.StringIO(_sample_message))) - self.assertTrue(len(self._box) == 4) + self.assertEqual(len(self._box), 4) keys.append(self._box.add(_sample_message)) - self.assertTrue(len(self._box) == 5) - self.assertTrue(self._box.get_string(keys[0]) == self._template % 0) + self.assertEqual(len(self._box), 5) + self.assertEqual(self._box.get_string(keys[0]), self._template % 0) for i in (1, 2, 3, 4): self._check_sample(self._box[keys[i]]) @@ -90,23 +90,23 @@ # (Used by test_remove() and test_delitem().) key0 = self._box.add(self._template % 0) key1 = self._box.add(self._template % 1) - self.assertTrue(len(self._box) == 2) + self.assertEqual(len(self._box), 2) method(key0) l = len(self._box) - self.assertTrue(l == 1, "actual l: %s" % l) + self.assertEqual(l, 1) self.assertRaises(KeyError, lambda: self._box[key0]) self.assertRaises(KeyError, lambda: method(key0)) - self.assertTrue(self._box.get_string(key1) == self._template % 1) + self.assertEqual(self._box.get_string(key1), self._template % 1) key2 = self._box.add(self._template % 2) - self.assertTrue(len(self._box) == 2) + self.assertEqual(len(self._box), 2) method(key2) l = len(self._box) - self.assertTrue(l == 1, "actual l: %s" % l) + self.assertEqual(l, 1) self.assertRaises(KeyError, lambda: self._box[key2]) self.assertRaises(KeyError, lambda: method(key2)) - self.assertTrue(self._box.get_string(key1) == self._template % 1) + self.assertEqual(self._box.get_string(key1), self._template % 1) method(key1) - self.assertTrue(len(self._box) == 0) + self.assertEqual(len(self._box), 0) self.assertRaises(KeyError, lambda: self._box[key1]) self.assertRaises(KeyError, lambda: method(key1)) @@ -114,35 +114,35 @@ # Discard messages key0 = self._box.add(self._template % 0) key1 = self._box.add(self._template % 1) - self.assertTrue(len(self._box) == 2) + self.assertEqual(len(self._box), 2) self._box.discard(key0) - self.assertTrue(len(self._box) == 1) + self.assertEqual(len(self._box), 1) self.assertRaises(KeyError, lambda: self._box[key0]) self._box.discard(key0) - self.assertTrue(len(self._box) == 1) + self.assertEqual(len(self._box), 1) self.assertRaises(KeyError, lambda: self._box[key0]) def test_get(self): # Retrieve messages using get() key0 = self._box.add(self._template % 0) msg = self._box.get(key0) - self.assertTrue(msg['from'] == 'foo') - self.assertTrue(msg.get_payload() == '0') - self.assertTrue(self._box.get('foo') is None) - self.assertTrue(self._box.get('foo', False) is False) + self.assertEqual(msg['from'], 'foo') + self.assertEqual(msg.get_payload(), '0') + self.assertIs(self._box.get('foo'), None) + self.assertFalse(self._box.get('foo', False)) self._box.close() self._box = self._factory(self._path, factory=rfc822.Message) key1 = self._box.add(self._template % 1) msg = self._box.get(key1) - self.assertTrue(msg['from'] == 'foo') - self.assertTrue(msg.fp.read() == '1') + self.assertEqual(msg['from'], 'foo') + self.assertEqual(msg.fp.read(), '1') def test_getitem(self): # Retrieve message using __getitem__() key0 = self._box.add(self._template % 0) msg = self._box[key0] - self.assertTrue(msg['from'] == 'foo') - self.assertTrue(msg.get_payload() == '0') + self.assertEqual(msg['from'], 'foo') + self.assertEqual(msg.get_payload(), '0') self.assertRaises(KeyError, lambda: self._box['foo']) self._box.discard(key0) self.assertRaises(KeyError, lambda: self._box[key0]) @@ -152,26 +152,26 @@ key0 = self._box.add(self._template % 0) key1 = self._box.add(_sample_message) msg0 = self._box.get_message(key0) - self.assertTrue(isinstance(msg0, mailbox.Message)) - self.assertTrue(msg0['from'] == 'foo') - self.assertTrue(msg0.get_payload() == '0') + self.assertIsInstance(msg0, mailbox.Message) + self.assertEqual(msg0['from'], 'foo') + self.assertEqual(msg0.get_payload(), '0') self._check_sample(self._box.get_message(key1)) def test_get_string(self): # Get string representations of messages key0 = self._box.add(self._template % 0) key1 = self._box.add(_sample_message) - self.assertTrue(self._box.get_string(key0) == self._template % 0) - self.assertTrue(self._box.get_string(key1) == _sample_message) + self.assertEqual(self._box.get_string(key0), self._template % 0) + self.assertEqual(self._box.get_string(key1), _sample_message) def test_get_file(self): # Get file representations of messages key0 = self._box.add(self._template % 0) key1 = self._box.add(_sample_message) - self.assertTrue(self._box.get_file(key0).read().replace(os.linesep, '\n') - == self._template % 0) - self.assertTrue(self._box.get_file(key1).read().replace(os.linesep, '\n') - == _sample_message) + self.assertEqual(self._box.get_file(key0).read().replace(os.linesep, '\n'), + self._template % 0) + self.assertEqual(self._box.get_file(key1).read().replace(os.linesep, '\n'), + _sample_message) def test_iterkeys(self): # Get keys using iterkeys() @@ -221,15 +221,16 @@ returned_keys.append(key) returned_values.append(value) if do_keys: - self.assertTrue(len(keys) == len(returned_keys)) - self.assertTrue(set(keys) == set(returned_keys)) + self.assertEqual(len(keys), len(returned_keys)) + self.assertEqual(set(keys), set(returned_keys)) if do_values: count = 0 for value in returned_values: - self.assertTrue(value['from'] == 'foo') - self.assertTrue(int(value.get_payload()) < repetitions) + self.assertEqual(value['from'], 'foo') + self.assertTrue(int(value.get_payload()) < repetitions, + (value.get_payload(), repetitions)) count += 1 - self.assertTrue(len(values) == count) + self.assertEqual(len(values), count) def test_has_key(self): # Check existence of keys using has_key() @@ -241,61 +242,61 @@ def _test_has_key_or_contains(self, method): # (Used by test_has_key() and test_contains().) - self.assertTrue(not method('foo')) + self.assertFalse(method('foo')) key0 = self._box.add(self._template % 0) self.assertTrue(method(key0)) - self.assertTrue(not method('foo')) + self.assertFalse(method('foo')) key1 = self._box.add(self._template % 1) self.assertTrue(method(key1)) self.assertTrue(method(key0)) - self.assertTrue(not method('foo')) + self.assertFalse(method('foo')) self._box.remove(key0) - self.assertTrue(not method(key0)) + self.assertFalse(method(key0)) self.assertTrue(method(key1)) - self.assertTrue(not method('foo')) + self.assertFalse(method('foo')) self._box.remove(key1) - self.assertTrue(not method(key1)) - self.assertTrue(not method(key0)) - self.assertTrue(not method('foo')) + self.assertFalse(method(key1)) + self.assertFalse(method(key0)) + self.assertFalse(method('foo')) def test_len(self, repetitions=10): # Get message count keys = [] for i in xrange(repetitions): - self.assertTrue(len(self._box) == i) + self.assertEqual(len(self._box), i) keys.append(self._box.add(self._template % i)) - self.assertTrue(len(self._box) == i + 1) + self.assertEqual(len(self._box), i + 1) for i in xrange(repetitions): - self.assertTrue(len(self._box) == repetitions - i) + self.assertEqual(len(self._box), repetitions - i) self._box.remove(keys[i]) - self.assertTrue(len(self._box) == repetitions - i - 1) + self.assertEqual(len(self._box), repetitions - i - 1) def test_set_item(self): # Modify messages using __setitem__() key0 = self._box.add(self._template % 'original 0') - self.assertTrue(self._box.get_string(key0) == \ - self._template % 'original 0') + self.assertEqual(self._box.get_string(key0), + self._template % 'original 0') key1 = self._box.add(self._template % 'original 1') - self.assertTrue(self._box.get_string(key1) == \ - self._template % 'original 1') + self.assertEqual(self._box.get_string(key1), + self._template % 'original 1') self._box[key0] = self._template % 'changed 0' - self.assertTrue(self._box.get_string(key0) == \ - self._template % 'changed 0') + self.assertEqual(self._box.get_string(key0), + self._template % 'changed 0') self._box[key1] = self._template % 'changed 1' - self.assertTrue(self._box.get_string(key1) == \ - self._template % 'changed 1') + self.assertEqual(self._box.get_string(key1), + self._template % 'changed 1') self._box[key0] = _sample_message self._check_sample(self._box[key0]) self._box[key1] = self._box[key0] self._check_sample(self._box[key1]) self._box[key0] = self._template % 'original 0' - self.assertTrue(self._box.get_string(key0) == - self._template % 'original 0') + self.assertEqual(self._box.get_string(key0), + self._template % 'original 0') self._check_sample(self._box[key1]) self.assertRaises(KeyError, lambda: self._box.__setitem__('foo', 'bar')) self.assertRaises(KeyError, lambda: self._box['foo']) - self.assertTrue(len(self._box) == 2) + self.assertEqual(len(self._box), 2) def test_clear(self, iterations=10): # Remove all messages using clear() @@ -303,29 +304,29 @@ for i in xrange(iterations): self._box.add(self._template % i) for i, key in enumerate(keys): - self.assertTrue(self._box.get_string(key) == self._template % i) + self.assertEqual(self._box.get_string(key), self._template % i) self._box.clear() - self.assertTrue(len(self._box) == 0) + self.assertEqual(len(self._box), 0) for i, key in enumerate(keys): self.assertRaises(KeyError, lambda: self._box.get_string(key)) def test_pop(self): # Get and remove a message using pop() key0 = self._box.add(self._template % 0) - self.assertTrue(key0 in self._box) + self.assertIn(key0, self._box) key1 = self._box.add(self._template % 1) - self.assertTrue(key1 in self._box) - self.assertTrue(self._box.pop(key0).get_payload() == '0') - self.assertTrue(key0 not in self._box) - self.assertTrue(key1 in self._box) + self.assertIn(key1, self._box) + self.assertEqual(self._box.pop(key0).get_payload(), '0') + self.assertNotIn(key0, self._box) + self.assertIn(key1, self._box) key2 = self._box.add(self._template % 2) - self.assertTrue(key2 in self._box) - self.assertTrue(self._box.pop(key2).get_payload() == '2') - self.assertTrue(key2 not in self._box) - self.assertTrue(key1 in self._box) - self.assertTrue(self._box.pop(key1).get_payload() == '1') - self.assertTrue(key1 not in self._box) - self.assertTrue(len(self._box) == 0) + self.assertIn(key2, self._box) + self.assertEqual(self._box.pop(key2).get_payload(), '2') + self.assertNotIn(key2, self._box) + self.assertIn(key1, self._box) + self.assertEqual(self._box.pop(key1).get_payload(), '1') + self.assertNotIn(key1, self._box) + self.assertEqual(len(self._box), 0) def test_popitem(self, iterations=10): # Get and remove an arbitrary (key, message) using popitem() @@ -335,11 +336,11 @@ seen = [] for i in xrange(10): key, msg = self._box.popitem() - self.assertTrue(key in keys) - self.assertTrue(key not in seen) + self.assertIn(key, keys) + self.assertNotIn(key, seen) seen.append(key) - self.assertTrue(int(msg.get_payload()) == keys.index(key)) - self.assertTrue(len(self._box) == 0) + self.assertEqual(int(msg.get_payload()), keys.index(key)) + self.assertEqual(len(self._box), 0) for key in keys: self.assertRaises(KeyError, lambda: self._box[key]) @@ -350,32 +351,32 @@ key2 = self._box.add(self._template % 'original 2') self._box.update({key0: self._template % 'changed 0', key2: _sample_message}) - self.assertTrue(len(self._box) == 3) - self.assertTrue(self._box.get_string(key0) == - self._template % 'changed 0') - self.assertTrue(self._box.get_string(key1) == - self._template % 'original 1') + self.assertEqual(len(self._box), 3) + self.assertEqual(self._box.get_string(key0), + self._template % 'changed 0') + self.assertEqual(self._box.get_string(key1), + self._template % 'original 1') self._check_sample(self._box[key2]) self._box.update([(key2, self._template % 'changed 2'), (key1, self._template % 'changed 1'), (key0, self._template % 'original 0')]) - self.assertTrue(len(self._box) == 3) - self.assertTrue(self._box.get_string(key0) == - self._template % 'original 0') - self.assertTrue(self._box.get_string(key1) == - self._template % 'changed 1') - self.assertTrue(self._box.get_string(key2) == - self._template % 'changed 2') + self.assertEqual(len(self._box), 3) + self.assertEqual(self._box.get_string(key0), + self._template % 'original 0') + self.assertEqual(self._box.get_string(key1), + self._template % 'changed 1') + self.assertEqual(self._box.get_string(key2), + self._template % 'changed 2') self.assertRaises(KeyError, lambda: self._box.update({'foo': 'bar', key0: self._template % "changed 0"})) - self.assertTrue(len(self._box) == 3) - self.assertTrue(self._box.get_string(key0) == - self._template % "changed 0") - self.assertTrue(self._box.get_string(key1) == - self._template % "changed 1") - self.assertTrue(self._box.get_string(key2) == - self._template % "changed 2") + self.assertEqual(len(self._box), 3) + self.assertEqual(self._box.get_string(key0), + self._template % "changed 0") + self.assertEqual(self._box.get_string(key1), + self._template % "changed 1") + self.assertEqual(self._box.get_string(key2), + self._template % "changed 2") def test_flush(self): # Write changes to disk @@ -383,11 +384,11 @@ def test_lock_unlock(self): # Lock and unlock the mailbox - self.assertTrue(not os.path.exists(self._get_lock_path())) + self.assertFalse(os.path.exists(self._get_lock_path())) self._box.lock() self.assertTrue(os.path.exists(self._get_lock_path())) self._box.unlock() - self.assertTrue(not os.path.exists(self._get_lock_path())) + self.assertFalse(os.path.exists(self._get_lock_path())) def test_close(self): # Close mailbox and flush changes to disk @@ -403,9 +404,9 @@ self._box.close() self._box = self._factory(self._path) keys = self._box.keys() - self.assertTrue(len(keys) == 3) + self.assertEqual(len(keys), 3) for key in keys: - self.assertTrue(self._box.get_string(key) in contents) + self.assertIn(self._box.get_string(key), contents) def test_dump_message(self): # Write message representations to disk @@ -413,8 +414,8 @@ _sample_message, StringIO.StringIO(_sample_message)): output = StringIO.StringIO() self._box._dump_message(input, output) - self.assertTrue(output.getvalue() == - _sample_message.replace('\n', os.linesep)) + self.assertEqual(output.getvalue(), + _sample_message.replace('\n', os.linesep)) output = StringIO.StringIO() self.assertRaises(TypeError, lambda: self._box._dump_message(None, output)) @@ -484,9 +485,9 @@ msg.set_flags('RF') key = self._box.add(msg) msg_returned = self._box.get_message(key) - self.assertTrue(isinstance(msg_returned, mailbox.MaildirMessage)) - self.assertTrue(msg_returned.get_subdir() == 'cur') - self.assertTrue(msg_returned.get_flags() == 'FR') + self.assertIsInstance(msg_returned, mailbox.MaildirMessage) + self.assertEqual(msg_returned.get_subdir(), 'cur') + self.assertEqual(msg_returned.get_flags(), 'FR') def test_set_MM(self): # Set with a MaildirMessage instance @@ -494,22 +495,22 @@ msg0.set_flags('TP') key = self._box.add(msg0) msg_returned = self._box.get_message(key) - self.assertTrue(msg_returned.get_subdir() == 'new') - self.assertTrue(msg_returned.get_flags() == 'PT') + self.assertEqual(msg_returned.get_subdir(), 'new') + self.assertEqual(msg_returned.get_flags(), 'PT') msg1 = mailbox.MaildirMessage(self._template % 1) self._box[key] = msg1 msg_returned = self._box.get_message(key) - self.assertTrue(msg_returned.get_subdir() == 'new') - self.assertTrue(msg_returned.get_flags() == '') - self.assertTrue(msg_returned.get_payload() == '1') + self.assertEqual(msg_returned.get_subdir(), 'new') + self.assertEqual(msg_returned.get_flags(), '') + self.assertEqual(msg_returned.get_payload(), '1') msg2 = mailbox.MaildirMessage(self._template % 2) msg2.set_info('2,S') self._box[key] = msg2 self._box[key] = self._template % 3 msg_returned = self._box.get_message(key) - self.assertTrue(msg_returned.get_subdir() == 'new') - self.assertTrue(msg_returned.get_flags() == 'S') - self.assertTrue(msg_returned.get_payload() == '3') + self.assertEqual(msg_returned.get_subdir(), 'new') + self.assertEqual(msg_returned.get_flags(), 'S') + self.assertEqual(msg_returned.get_payload(), '3') def test_consistent_factory(self): # Add a message. @@ -524,7 +525,7 @@ box = mailbox.Maildir(self._path, factory=FakeMessage) box.colon = self._box.colon msg2 = box.get_message(key) - self.assertTrue(isinstance(msg2, FakeMessage)) + self.assertIsInstance(msg2, FakeMessage) def test_initialize_new(self): # Initialize a non-existent mailbox @@ -559,9 +560,9 @@ self._box.add_folder('one') self._box.add_folder('two') self._box.add_folder('three') - self.assertTrue(len(self._box.list_folders()) == 3) - self.assertTrue(set(self._box.list_folders()) == - set(('one', 'two', 'three'))) + self.assertEqual(len(self._box.list_folders()), 3) + self.assertEqual(set(self._box.list_folders()), + set(('one', 'two', 'three'))) def test_get_folder(self): # Open folders @@ -570,27 +571,27 @@ folder0.add(self._template % 'bar') self.assertTrue(os.path.isdir(os.path.join(self._path, '.foo.bar'))) folder1 = self._box.get_folder('foo.bar') - self.assertTrue(folder1.get_string(folder1.keys()[0]) == \ - self._template % 'bar') + self.assertEqual(folder1.get_string(folder1.keys()[0]), + self._template % 'bar') def test_add_and_remove_folders(self): # Delete folders self._box.add_folder('one') self._box.add_folder('two') - self.assertTrue(len(self._box.list_folders()) == 2) - self.assertTrue(set(self._box.list_folders()) == set(('one', 'two'))) + self.assertEqual(len(self._box.list_folders()), 2) + self.assertEqual(set(self._box.list_folders()), set(('one', 'two'))) self._box.remove_folder('one') - self.assertTrue(len(self._box.list_folders()) == 1) - self.assertTrue(set(self._box.list_folders()) == set(('two',))) + self.assertEqual(len(self._box.list_folders()), 1) + self.assertEqual(set(self._box.list_folders()), set(('two',))) self._box.add_folder('three') - self.assertTrue(len(self._box.list_folders()) == 2) - self.assertTrue(set(self._box.list_folders()) == set(('two', 'three'))) + self.assertEqual(len(self._box.list_folders()), 2) + self.assertEqual(set(self._box.list_folders()), set(('two', 'three'))) self._box.remove_folder('three') - self.assertTrue(len(self._box.list_folders()) == 1) - self.assertTrue(set(self._box.list_folders()) == set(('two',))) + self.assertEqual(len(self._box.list_folders()), 1) + self.assertEqual(set(self._box.list_folders()), set(('two',))) self._box.remove_folder('two') - self.assertTrue(len(self._box.list_folders()) == 0) - self.assertTrue(self._box.list_folders() == []) + self.assertEqual(len(self._box.list_folders()), 0) + self.assertEqual(self._box.list_folders(), []) def test_clean(self): # Remove old files from 'tmp' @@ -609,7 +610,7 @@ os.utime(foo_path, (time.time() - 129600 - 2, foo_stat.st_mtime)) self._box.clean() - self.assertTrue(not os.path.exists(foo_path)) + self.assertFalse(os.path.exists(foo_path)) self.assertTrue(os.path.exists(bar_path)) def test_create_tmp(self, repetitions=10): @@ -661,30 +662,30 @@ def test_refresh(self): # Update the table of contents - self.assertTrue(self._box._toc == {}) + self.assertEqual(self._box._toc, {}) key0 = self._box.add(self._template % 0) key1 = self._box.add(self._template % 1) - self.assertTrue(self._box._toc == {}) + self.assertEqual(self._box._toc, {}) self._box._refresh() - self.assertTrue(self._box._toc == {key0: os.path.join('new', key0), - key1: os.path.join('new', key1)}) + self.assertEqual(self._box._toc, {key0: os.path.join('new', key0), + key1: os.path.join('new', key1)}) key2 = self._box.add(self._template % 2) - self.assertTrue(self._box._toc == {key0: os.path.join('new', key0), - key1: os.path.join('new', key1)}) + self.assertEqual(self._box._toc, {key0: os.path.join('new', key0), + key1: os.path.join('new', key1)}) self._box._refresh() - self.assertTrue(self._box._toc == {key0: os.path.join('new', key0), - key1: os.path.join('new', key1), - key2: os.path.join('new', key2)}) + self.assertEqual(self._box._toc, {key0: os.path.join('new', key0), + key1: os.path.join('new', key1), + key2: os.path.join('new', key2)}) def test_lookup(self): # Look up message subpaths in the TOC self.assertRaises(KeyError, lambda: self._box._lookup('foo')) key0 = self._box.add(self._template % 0) - self.assertTrue(self._box._lookup(key0) == os.path.join('new', key0)) + self.assertEqual(self._box._lookup(key0), os.path.join('new', key0)) os.remove(os.path.join(self._path, 'new', key0)) - self.assertTrue(self._box._toc == {key0: os.path.join('new', key0)}) + self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)}) self.assertRaises(KeyError, lambda: self._box._lookup(key0)) - self.assertTrue(self._box._toc == {}) + self.assertEqual(self._box._toc, {}) def test_lock_unlock(self): # Lock and unlock the mailbox. For Maildir, this does nothing. @@ -698,10 +699,10 @@ return None box = self._factory(self._path, factory=dummy_factory) folder = box.add_folder('folder1') - self.assertTrue(folder._factory is dummy_factory) + self.assertIs(folder._factory, dummy_factory) folder1_alias = box.get_folder('folder1') - self.assertTrue(folder1_alias._factory is dummy_factory) + self.assertIs(folder1_alias._factory, dummy_factory) def test_directory_in_folder (self): # Test that mailboxes still work if there's a stray extra directory @@ -728,7 +729,7 @@ os.umask(orig_umask) path = os.path.join(self._path, self._box._lookup(key)) mode = os.stat(path).st_mode - self.assertTrue(mode & 0111 == 0) + self.assertEqual(mode & 0111, 0) def test_folder_file_perms(self): # From bug #3228, we want to verify that the file created inside a Maildir @@ -790,8 +791,8 @@ def test_add_from_string(self): # Add a string starting with 'From ' to the mailbox key = self._box.add('From foo at bar blah\nFrom: foo\n\n0') - self.assertTrue(self._box[key].get_from() == 'foo at bar blah') - self.assertTrue(self._box[key].get_payload() == '0') + self.assertEqual(self._box[key].get_from(), 'foo at bar blah') + self.assertEqual(self._box[key].get_payload(), '0') def test_add_mbox_or_mmdf_message(self): # Add an mboxMessage or MMDFMessage @@ -807,11 +808,11 @@ self._box.close() mtime = os.path.getmtime(self._path) self._box = self._factory(self._path) - self.assertTrue(len(self._box) == 3) + self.assertEqual(len(self._box), 3) for key in self._box.iterkeys(): - self.assertTrue(self._box.get_string(key) in values) + self.assertIn(self._box.get_string(key), values) self._box.close() - self.assertTrue(mtime == os.path.getmtime(self._path)) + self.assertEqual(mtime, os.path.getmtime(self._path)) def test_add_and_close(self): # Verifying that closing a mailbox doesn't change added items @@ -823,7 +824,8 @@ self._box._file.seek(0) contents = self._box._file.read() self._box.close() - self.assertTrue(contents == open(self._path, 'rb').read()) + with open(self._path, 'rb') as f: + self.assertEqual(contents, f.read()) self._box = self._factory(self._path) def test_lock_conflict(self): @@ -905,9 +907,9 @@ self._box.add_folder('one') self._box.add_folder('two') self._box.add_folder('three') - self.assertTrue(len(self._box.list_folders()) == 3) - self.assertTrue(set(self._box.list_folders()) == - set(('one', 'two', 'three'))) + self.assertEqual(len(self._box.list_folders()), 3) + self.assertEqual(set(self._box.list_folders()), + set(('one', 'two', 'three'))) def test_get_folder(self): # Open folders @@ -920,52 +922,52 @@ folder0.add(self._template % 'bar') self.assertTrue(os.path.isdir(os.path.join(self._path, 'foo.bar'))) folder1 = self._box.get_folder('foo.bar') - self.assertTrue(folder1.get_string(folder1.keys()[0]) == \ - self._template % 'bar') + self.assertEqual(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.assertTrue(new_folder._factory is self._box._factory) - self.assertTrue(folder0._factory is self._box._factory) + self.assertIs(new_folder._factory, self._box._factory) + self.assertIs(folder0._factory, self._box._factory) def test_add_and_remove_folders(self): # Delete folders self._box.add_folder('one') self._box.add_folder('two') - self.assertTrue(len(self._box.list_folders()) == 2) - self.assertTrue(set(self._box.list_folders()) == set(('one', 'two'))) + self.assertEqual(len(self._box.list_folders()), 2) + self.assertEqual(set(self._box.list_folders()), set(('one', 'two'))) self._box.remove_folder('one') - self.assertTrue(len(self._box.list_folders()) == 1) - self.assertTrue(set(self._box.list_folders()) == set(('two',))) + self.assertEqual(len(self._box.list_folders()), 1) + self.assertEqual(set(self._box.list_folders()), set(('two', ))) self._box.add_folder('three') - self.assertTrue(len(self._box.list_folders()) == 2) - self.assertTrue(set(self._box.list_folders()) == set(('two', 'three'))) + self.assertEqual(len(self._box.list_folders()), 2) + self.assertEqual(set(self._box.list_folders()), set(('two', 'three'))) self._box.remove_folder('three') - self.assertTrue(len(self._box.list_folders()) == 1) - self.assertTrue(set(self._box.list_folders()) == set(('two',))) + self.assertEqual(len(self._box.list_folders()), 1) + self.assertEqual(set(self._box.list_folders()), set(('two', ))) self._box.remove_folder('two') - self.assertTrue(len(self._box.list_folders()) == 0) - self.assertTrue(self._box.list_folders() == []) + self.assertEqual(len(self._box.list_folders()), 0) + self.assertEqual(self._box.list_folders(), []) def test_sequences(self): # Get and set sequences - self.assertTrue(self._box.get_sequences() == {}) + self.assertEqual(self._box.get_sequences(), {}) msg0 = mailbox.MHMessage(self._template % 0) msg0.add_sequence('foo') key0 = self._box.add(msg0) - self.assertTrue(self._box.get_sequences() == {'foo':[key0]}) + self.assertEqual(self._box.get_sequences(), {'foo':[key0]}) msg1 = mailbox.MHMessage(self._template % 1) msg1.set_sequences(['bar', 'replied', 'foo']) key1 = self._box.add(msg1) - self.assertTrue(self._box.get_sequences() == - {'foo':[key0, key1], 'bar':[key1], 'replied':[key1]}) + self.assertEqual(self._box.get_sequences(), + {'foo':[key0, key1], 'bar':[key1], 'replied':[key1]}) msg0.set_sequences(['flagged']) self._box[key0] = msg0 - self.assertTrue(self._box.get_sequences() == - {'foo':[key1], 'bar':[key1], 'replied':[key1], - 'flagged':[key0]}) + self.assertEqual(self._box.get_sequences(), + {'foo':[key1], 'bar':[key1], 'replied':[key1], + 'flagged':[key0]}) self._box.remove(key1) - self.assertTrue(self._box.get_sequences() == {'flagged':[key0]}) + self.assertEqual(self._box.get_sequences(), {'flagged':[key0]}) def test_issue2625(self): msg0 = mailbox.MHMessage(self._template % 0) @@ -987,19 +989,19 @@ key1 = self._box.add(msg1) key2 = self._box.add(msg2) key3 = self._box.add(msg3) - self.assertTrue(self._box.get_sequences() == - {'foo':[key0,key1,key2,key3], 'unseen':[key0], - 'flagged':[key2], 'bar':[key3], 'replied':[key3]}) + self.assertEqual(self._box.get_sequences(), + {'foo':[key0,key1,key2,key3], 'unseen':[key0], + 'flagged':[key2], 'bar':[key3], 'replied':[key3]}) self._box.remove(key2) - self.assertTrue(self._box.get_sequences() == - {'foo':[key0,key1,key3], 'unseen':[key0], 'bar':[key3], - 'replied':[key3]}) + self.assertEqual(self._box.get_sequences(), + {'foo':[key0,key1,key3], 'unseen':[key0], 'bar':[key3], + 'replied':[key3]}) self._box.pack() - self.assertTrue(self._box.keys() == [1, 2, 3]) + self.assertEqual(self._box.keys(), [1, 2, 3]) key0 = key0 key1 = key0 + 1 key2 = key1 + 1 - self.assertTrue(self._box.get_sequences() == + self.assertEqual(self._box.get_sequences(), {'foo':[1, 2, 3], 'unseen':[1], 'bar':[3], 'replied':[3]}) # Test case for packing while holding the mailbox locked. @@ -1013,9 +1015,9 @@ self._box.lock() self._box.pack() self._box.unlock() - self.assertTrue(self._box.get_sequences() == - {'foo':[1, 2, 3, 4, 5], - 'unseen':[1], 'bar':[3], 'replied':[3]}) + self.assertEqual(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') @@ -1033,21 +1035,21 @@ def test_labels(self): # Get labels from the mailbox - self.assertTrue(self._box.get_labels() == []) + self.assertEqual(self._box.get_labels(), []) msg0 = mailbox.BabylMessage(self._template % 0) msg0.add_label('foo') key0 = self._box.add(msg0) - self.assertTrue(self._box.get_labels() == ['foo']) + self.assertEqual(self._box.get_labels(), ['foo']) msg1 = mailbox.BabylMessage(self._template % 1) msg1.set_labels(['bar', 'answered', 'foo']) key1 = self._box.add(msg1) - self.assertTrue(set(self._box.get_labels()) == set(['foo', 'bar'])) + self.assertEqual(set(self._box.get_labels()), set(['foo', 'bar'])) msg0.set_labels(['blah', 'filed']) self._box[key0] = msg0 - self.assertTrue(set(self._box.get_labels()) == - set(['foo', 'bar', 'blah'])) + self.assertEqual(set(self._box.get_labels()), + set(['foo', 'bar', 'blah'])) self._box.remove(key1) - self.assertTrue(set(self._box.get_labels()) == set(['blah'])) + self.assertEqual(set(self._box.get_labels()), set(['blah'])) class TestMessage(TestBase): @@ -1087,12 +1089,12 @@ # Initialize without arguments msg = self._factory() self._post_initialize_hook(msg) - self.assertTrue(isinstance(msg, email.message.Message)) - self.assertTrue(isinstance(msg, mailbox.Message)) - self.assertTrue(isinstance(msg, self._factory)) - self.assertTrue(msg.keys() == []) - self.assertTrue(not msg.is_multipart()) - self.assertTrue(msg.get_payload() == None) + self.assertIsInstance(msg, email.message.Message) + self.assertIsInstance(msg, mailbox.Message) + self.assertIsInstance(msg, self._factory) + self.assertEqual(msg.keys(), []) + self.assertFalse(msg.is_multipart()) + self.assertEqual(msg.get_payload(), None) def test_initialize_incorrectly(self): # Initialize with invalid argument @@ -1127,72 +1129,73 @@ _factory = mailbox.MaildirMessage def _post_initialize_hook(self, msg): - self.assertTrue(msg._subdir == 'new') - self.assertTrue(msg._info == '') + self.assertEqual(msg._subdir, 'new') + self.assertEqual(msg._info,'') def test_subdir(self): # Use get_subdir() and set_subdir() msg = mailbox.MaildirMessage(_sample_message) - self.assertTrue(msg.get_subdir() == 'new') + self.assertEqual(msg.get_subdir(), 'new') msg.set_subdir('cur') - self.assertTrue(msg.get_subdir() == 'cur') + self.assertEqual(msg.get_subdir(), 'cur') msg.set_subdir('new') - self.assertTrue(msg.get_subdir() == 'new') + self.assertEqual(msg.get_subdir(), 'new') self.assertRaises(ValueError, lambda: msg.set_subdir('tmp')) - self.assertTrue(msg.get_subdir() == 'new') + self.assertEqual(msg.get_subdir(), 'new') msg.set_subdir('new') - self.assertTrue(msg.get_subdir() == 'new') + self.assertEqual(msg.get_subdir(), 'new') self._check_sample(msg) def test_flags(self): # Use get_flags(), set_flags(), add_flag(), remove_flag() msg = mailbox.MaildirMessage(_sample_message) - self.assertTrue(msg.get_flags() == '') - self.assertTrue(msg.get_subdir() == 'new') + self.assertEqual(msg.get_flags(), '') + self.assertEqual(msg.get_subdir(), 'new') msg.set_flags('F') - self.assertTrue(msg.get_subdir() == 'new') - self.assertTrue(msg.get_flags() == 'F') + self.assertEqual(msg.get_subdir(), 'new') + self.assertEqual(msg.get_flags(), 'F') msg.set_flags('SDTP') - self.assertTrue(msg.get_flags() == 'DPST') + self.assertEqual(msg.get_flags(), 'DPST') msg.add_flag('FT') - self.assertTrue(msg.get_flags() == 'DFPST') + self.assertEqual(msg.get_flags(), 'DFPST') msg.remove_flag('TDRP') - self.assertTrue(msg.get_flags() == 'FS') - self.assertTrue(msg.get_subdir() == 'new') + self.assertEqual(msg.get_flags(), 'FS') + self.assertEqual(msg.get_subdir(), 'new') self._check_sample(msg) def test_date(self): # Use get_date() and set_date() msg = mailbox.MaildirMessage(_sample_message) - self.assertTrue(abs(msg.get_date() - time.time()) < 60) + diff = msg.get_date() - time.time() + self.assertTrue(abs(diff) < 60, diff) msg.set_date(0.0) - self.assertTrue(msg.get_date() == 0.0) + self.assertEqual(msg.get_date(), 0.0) def test_info(self): # Use get_info() and set_info() msg = mailbox.MaildirMessage(_sample_message) - self.assertTrue(msg.get_info() == '') + self.assertEqual(msg.get_info(), '') msg.set_info('1,foo=bar') - self.assertTrue(msg.get_info() == '1,foo=bar') + self.assertEqual(msg.get_info(), '1,foo=bar') self.assertRaises(TypeError, lambda: msg.set_info(None)) self._check_sample(msg) def test_info_and_flags(self): # Test interaction of info and flag methods msg = mailbox.MaildirMessage(_sample_message) - self.assertTrue(msg.get_info() == '') + self.assertEqual(msg.get_info(), '') msg.set_flags('SF') - self.assertTrue(msg.get_flags() == 'FS') - self.assertTrue(msg.get_info() == '2,FS') + self.assertEqual(msg.get_flags(), 'FS') + self.assertEqual(msg.get_info(), '2,FS') msg.set_info('1,') - self.assertTrue(msg.get_flags() == '') - self.assertTrue(msg.get_info() == '1,') + self.assertEqual(msg.get_flags(), '') + self.assertEqual(msg.get_info(), '1,') msg.remove_flag('RPT') - self.assertTrue(msg.get_flags() == '') - self.assertTrue(msg.get_info() == '1,') + self.assertEqual(msg.get_flags(), '') + self.assertEqual(msg.get_info(), '1,') msg.add_flag('D') - self.assertTrue(msg.get_flags() == 'D') - self.assertTrue(msg.get_info() == '2,D') + self.assertEqual(msg.get_flags(), 'D') + self.assertEqual(msg.get_info(), '2,D') self._check_sample(msg) @@ -1208,14 +1211,14 @@ msg = mailbox.Message(_sample_message) msg.set_unixfrom('From foo at bar blah') msg = mailbox.mboxMessage(msg) - self.assertTrue(msg.get_from() == 'foo at bar blah', msg.get_from()) + self.assertEqual(msg.get_from(), 'foo at bar blah') def test_from(self): # Get and set "From " line msg = mailbox.mboxMessage(_sample_message) self._check_from(msg) msg.set_from('foo bar') - self.assertTrue(msg.get_from() == 'foo bar') + self.assertEqual(msg.get_from(), 'foo bar') msg.set_from('foo at bar', True) self._check_from(msg, 'foo at bar') msg.set_from('blah at temp', time.localtime()) @@ -1224,15 +1227,15 @@ def test_flags(self): # Use get_flags(), set_flags(), add_flag(), remove_flag() msg = mailbox.mboxMessage(_sample_message) - self.assertTrue(msg.get_flags() == '') + self.assertEqual(msg.get_flags(), '') msg.set_flags('F') - self.assertTrue(msg.get_flags() == 'F') + self.assertEqual(msg.get_flags(), 'F') msg.set_flags('XODR') - self.assertTrue(msg.get_flags() == 'RODX') + self.assertEqual(msg.get_flags(), 'RODX') msg.add_flag('FA') - self.assertTrue(msg.get_flags() == 'RODFAX') + self.assertEqual(msg.get_flags(), 'RODFAX') msg.remove_flag('FDXA') - self.assertTrue(msg.get_flags() == 'RO') + self.assertEqual(msg.get_flags(), 'RO') self._check_sample(msg) def _check_from(self, msg, sender=None): @@ -1240,7 +1243,7 @@ if sender is None: sender = "MAILER-DAEMON" self.assertTrue(re.match(sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:" - r"\d{2} \d{4}", msg.get_from()) is not None) + r"\d{2} \d{4}", msg.get_from())) class TestMboxMessage(_TestMboxMMDFMessage): @@ -1253,30 +1256,30 @@ _factory = mailbox.MHMessage def _post_initialize_hook(self, msg): - self.assertTrue(msg._sequences == []) + self.assertEqual(msg._sequences, []) def test_sequences(self): # Get, set, join, and leave sequences msg = mailbox.MHMessage(_sample_message) - self.assertTrue(msg.get_sequences() == []) + self.assertEqual(msg.get_sequences(), []) msg.set_sequences(['foobar']) - self.assertTrue(msg.get_sequences() == ['foobar']) + self.assertEqual(msg.get_sequences(), ['foobar']) msg.set_sequences([]) - self.assertTrue(msg.get_sequences() == []) + self.assertEqual(msg.get_sequences(), []) msg.add_sequence('unseen') - self.assertTrue(msg.get_sequences() == ['unseen']) + self.assertEqual(msg.get_sequences(), ['unseen']) msg.add_sequence('flagged') - self.assertTrue(msg.get_sequences() == ['unseen', 'flagged']) + self.assertEqual(msg.get_sequences(), ['unseen', 'flagged']) msg.add_sequence('flagged') - self.assertTrue(msg.get_sequences() == ['unseen', 'flagged']) + self.assertEqual(msg.get_sequences(), ['unseen', 'flagged']) msg.remove_sequence('unseen') - self.assertTrue(msg.get_sequences() == ['flagged']) + self.assertEqual(msg.get_sequences(), ['flagged']) msg.add_sequence('foobar') - self.assertTrue(msg.get_sequences() == ['flagged', 'foobar']) + self.assertEqual(msg.get_sequences(), ['flagged', 'foobar']) msg.remove_sequence('replied') - self.assertTrue(msg.get_sequences() == ['flagged', 'foobar']) + self.assertEqual(msg.get_sequences(), ['flagged', 'foobar']) msg.set_sequences(['foobar', 'replied']) - self.assertTrue(msg.get_sequences() == ['foobar', 'replied']) + self.assertEqual(msg.get_sequences(), ['foobar', 'replied']) class TestBabylMessage(TestMessage): @@ -1284,54 +1287,54 @@ _factory = mailbox.BabylMessage def _post_initialize_hook(self, msg): - self.assertTrue(msg._labels == []) + self.assertEqual(msg._labels, []) def test_labels(self): # Get, set, join, and leave labels msg = mailbox.BabylMessage(_sample_message) - self.assertTrue(msg.get_labels() == []) + self.assertEqual(msg.get_labels(), []) msg.set_labels(['foobar']) - self.assertTrue(msg.get_labels() == ['foobar']) + self.assertEqual(msg.get_labels(), ['foobar']) msg.set_labels([]) - self.assertTrue(msg.get_labels() == []) + self.assertEqual(msg.get_labels(), []) msg.add_label('filed') - self.assertTrue(msg.get_labels() == ['filed']) + self.assertEqual(msg.get_labels(), ['filed']) msg.add_label('resent') - self.assertTrue(msg.get_labels() == ['filed', 'resent']) + self.assertEqual(msg.get_labels(), ['filed', 'resent']) msg.add_label('resent') - self.assertTrue(msg.get_labels() == ['filed', 'resent']) + self.assertEqual(msg.get_labels(), ['filed', 'resent']) msg.remove_label('filed') - self.assertTrue(msg.get_labels() == ['resent']) + self.assertEqual(msg.get_labels(), ['resent']) msg.add_label('foobar') - self.assertTrue(msg.get_labels() == ['resent', 'foobar']) + self.assertEqual(msg.get_labels(), ['resent', 'foobar']) msg.remove_label('unseen') - self.assertTrue(msg.get_labels() == ['resent', 'foobar']) + self.assertEqual(msg.get_labels(), ['resent', 'foobar']) msg.set_labels(['foobar', 'answered']) - self.assertTrue(msg.get_labels() == ['foobar', 'answered']) + self.assertEqual(msg.get_labels(), ['foobar', 'answered']) def test_visible(self): # Get, set, and update visible headers msg = mailbox.BabylMessage(_sample_message) visible = msg.get_visible() - self.assertTrue(visible.keys() == []) - self.assertTrue(visible.get_payload() is None) + self.assertEqual(visible.keys(), []) + self.assertIs(visible.get_payload(), None) visible['User-Agent'] = 'FooBar 1.0' visible['X-Whatever'] = 'Blah' - self.assertTrue(msg.get_visible().keys() == []) + self.assertEqual(msg.get_visible().keys(), []) msg.set_visible(visible) visible = msg.get_visible() - self.assertTrue(visible.keys() == ['User-Agent', 'X-Whatever']) - self.assertTrue(visible['User-Agent'] == 'FooBar 1.0') - self.assertTrue(visible['X-Whatever'] == 'Blah') - self.assertTrue(visible.get_payload() is None) + self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever']) + self.assertEqual(visible['User-Agent'], 'FooBar 1.0') + self.assertEqual(visible['X-Whatever'], 'Blah') + self.assertIs(visible.get_payload(), None) msg.update_visible() - self.assertTrue(visible.keys() == ['User-Agent', 'X-Whatever']) - self.assertTrue(visible.get_payload() is None) + self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever']) + self.assertIs(visible.get_payload(), None) visible = msg.get_visible() - self.assertTrue(visible.keys() == ['User-Agent', 'Date', 'From', 'To', - 'Subject']) + self.assertEqual(visible.keys(), ['User-Agent', 'Date', 'From', 'To', + 'Subject']) for header in ('User-Agent', 'Date', 'From', 'To', 'Subject'): - self.assertTrue(visible[header] == msg[header]) + self.assertEqual(visible[header], msg[header]) class TestMMDFMessage(_TestMboxMMDFMessage): @@ -1374,9 +1377,9 @@ date = msg_maildir.get_date() msg = mailbox.MaildirMessage(msg_maildir) self._check_sample(msg) - self.assertTrue(msg.get_flags() == 'DFPRST') - self.assertTrue(msg.get_subdir() == 'cur') - self.assertTrue(msg.get_date() == date) + self.assertEqual(msg.get_flags(), 'DFPRST') + self.assertEqual(msg.get_subdir(), 'cur') + self.assertEqual(msg.get_date(), date) def test_maildir_to_mboxmmdf(self): # Convert MaildirMessage to mboxmessage and MMDFMessage @@ -1388,11 +1391,11 @@ for setting, result in pairs: msg_maildir.set_flags(setting) msg = class_(msg_maildir) - self.assertTrue(msg.get_flags() == result) - self.assertTrue(msg.get_from() == 'MAILER-DAEMON %s' % - time.asctime(time.gmtime(0.0))) + self.assertEqual(msg.get_flags(), result) + self.assertEqual(msg.get_from(), 'MAILER-DAEMON %s' % + time.asctime(time.gmtime(0.0))) msg_maildir.set_subdir('cur') - self.assertTrue(class_(msg_maildir).get_flags() == 'RODFA') + self.assertEqual(class_(msg_maildir).get_flags(), 'RODFA') def test_maildir_to_mh(self): # Convert MaildirMessage to MHMessage @@ -1402,8 +1405,8 @@ ('T', ['unseen']), ('DFPRST', ['replied', 'flagged'])) for setting, result in pairs: msg_maildir.set_flags(setting) - self.assertTrue(mailbox.MHMessage(msg_maildir).get_sequences() == \ - result) + self.assertEqual(mailbox.MHMessage(msg_maildir).get_sequences(), + result) def test_maildir_to_babyl(self): # Convert MaildirMessage to Babyl @@ -1414,8 +1417,8 @@ ('DFPRST', ['deleted', 'answered', 'forwarded'])) for setting, result in pairs: msg_maildir.set_flags(setting) - self.assertTrue(mailbox.BabylMessage(msg_maildir).get_labels() == \ - result) + self.assertEqual(mailbox.BabylMessage(msg_maildir).get_labels(), + result) def test_mboxmmdf_to_maildir(self): # Convert mboxMessage and MMDFMessage to MaildirMessage @@ -1427,11 +1430,11 @@ for setting, result in pairs: msg_mboxMMDF.set_flags(setting) msg = mailbox.MaildirMessage(msg_mboxMMDF) - self.assertTrue(msg.get_flags() == result) - self.assertTrue(msg.get_date() == 0.0, msg.get_date()) + self.assertEqual(msg.get_flags(), result) + self.assertEqual(msg.get_date(), 0.0) msg_mboxMMDF.set_flags('O') - self.assertTrue(mailbox.MaildirMessage(msg_mboxMMDF).get_subdir() == \ - 'cur') + self.assertEqual(mailbox.MaildirMessage(msg_mboxMMDF).get_subdir(), + 'cur') def test_mboxmmdf_to_mboxmmdf(self): # Convert mboxMessage and MMDFMessage to mboxMessage and MMDFMessage @@ -1441,8 +1444,8 @@ msg_mboxMMDF.set_from('foo at bar') for class2_ in (mailbox.mboxMessage, mailbox.MMDFMessage): msg2 = class2_(msg_mboxMMDF) - self.assertTrue(msg2.get_flags() == 'RODFA') - self.assertTrue(msg2.get_from() == 'foo at bar') + self.assertEqual(msg2.get_flags(), 'RODFA') + self.assertEqual(msg2.get_from(), 'foo at bar') def test_mboxmmdf_to_mh(self): # Convert mboxMessage and MMDFMessage to MHMessage @@ -1454,8 +1457,8 @@ ('RODFA', ['replied', 'flagged'])) for setting, result in pairs: msg_mboxMMDF.set_flags(setting) - self.assertTrue(mailbox.MHMessage(msg_mboxMMDF).get_sequences() \ - == result) + self.assertEqual(mailbox.MHMessage(msg_mboxMMDF).get_sequences(), + result) def test_mboxmmdf_to_babyl(self): # Convert mboxMessage and MMDFMessage to BabylMessage @@ -1467,7 +1470,7 @@ ('RODFA', ['deleted', 'answered'])) for setting, result in pairs: msg.set_flags(setting) - self.assertTrue(mailbox.BabylMessage(msg).get_labels() == result) + self.assertEqual(mailbox.BabylMessage(msg).get_labels(), result) def test_mh_to_maildir(self): # Convert MHMessage to MaildirMessage @@ -1475,14 +1478,14 @@ for setting, result in pairs: msg = mailbox.MHMessage(_sample_message) msg.add_sequence(setting) - self.assertTrue(mailbox.MaildirMessage(msg).get_flags() == result) - self.assertTrue(mailbox.MaildirMessage(msg).get_subdir() == 'cur') + self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), result) + self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur') msg = mailbox.MHMessage(_sample_message) msg.add_sequence('unseen') msg.add_sequence('replied') msg.add_sequence('flagged') - self.assertTrue(mailbox.MaildirMessage(msg).get_flags() == 'FR') - self.assertTrue(mailbox.MaildirMessage(msg).get_subdir() == 'cur') + self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), 'FR') + self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur') def test_mh_to_mboxmmdf(self): # Convert MHMessage to mboxMessage and MMDFMessage @@ -1491,13 +1494,13 @@ msg = mailbox.MHMessage(_sample_message) msg.add_sequence(setting) for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage): - self.assertTrue(class_(msg).get_flags() == result) + self.assertEqual(class_(msg).get_flags(), result) msg = mailbox.MHMessage(_sample_message) msg.add_sequence('unseen') msg.add_sequence('replied') msg.add_sequence('flagged') for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage): - self.assertTrue(class_(msg).get_flags() == 'OFA') + self.assertEqual(class_(msg).get_flags(), 'OFA') def test_mh_to_mh(self): # Convert MHMessage to MHMessage @@ -1505,8 +1508,8 @@ msg.add_sequence('unseen') msg.add_sequence('replied') msg.add_sequence('flagged') - self.assertTrue(mailbox.MHMessage(msg).get_sequences() == \ - ['unseen', 'replied', 'flagged']) + self.assertEqual(mailbox.MHMessage(msg).get_sequences(), + ['unseen', 'replied', 'flagged']) def test_mh_to_babyl(self): # Convert MHMessage to BabylMessage @@ -1515,13 +1518,13 @@ for setting, result in pairs: msg = mailbox.MHMessage(_sample_message) msg.add_sequence(setting) - self.assertTrue(mailbox.BabylMessage(msg).get_labels() == result) + self.assertEqual(mailbox.BabylMessage(msg).get_labels(), result) msg = mailbox.MHMessage(_sample_message) msg.add_sequence('unseen') msg.add_sequence('replied') msg.add_sequence('flagged') - self.assertTrue(mailbox.BabylMessage(msg).get_labels() == \ - ['unseen', 'answered']) + self.assertEqual(mailbox.BabylMessage(msg).get_labels(), + ['unseen', 'answered']) def test_babyl_to_maildir(self): # Convert BabylMessage to MaildirMessage @@ -1531,14 +1534,14 @@ for setting, result in pairs: msg = mailbox.BabylMessage(_sample_message) msg.add_label(setting) - self.assertTrue(mailbox.MaildirMessage(msg).get_flags() == result) - self.assertTrue(mailbox.MaildirMessage(msg).get_subdir() == 'cur') + self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), result) + self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur') msg = mailbox.BabylMessage(_sample_message) for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded', 'edited', 'resent'): msg.add_label(label) - self.assertTrue(mailbox.MaildirMessage(msg).get_flags() == 'PRT') - self.assertTrue(mailbox.MaildirMessage(msg).get_subdir() == 'cur') + self.assertEqual(mailbox.MaildirMessage(msg).get_flags(), 'PRT') + self.assertEqual(mailbox.MaildirMessage(msg).get_subdir(), 'cur') def test_babyl_to_mboxmmdf(self): # Convert BabylMessage to mboxMessage and MMDFMessage @@ -1549,13 +1552,13 @@ for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage): msg = mailbox.BabylMessage(_sample_message) msg.add_label(setting) - self.assertTrue(class_(msg).get_flags() == result) + self.assertEqual(class_(msg).get_flags(), result) msg = mailbox.BabylMessage(_sample_message) for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded', 'edited', 'resent'): msg.add_label(label) for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage): - self.assertTrue(class_(msg).get_flags() == 'ODA') + self.assertEqual(class_(msg).get_flags(), 'ODA') def test_babyl_to_mh(self): # Convert BabylMessage to MHMessage @@ -1565,13 +1568,13 @@ for setting, result in pairs: msg = mailbox.BabylMessage(_sample_message) msg.add_label(setting) - self.assertTrue(mailbox.MHMessage(msg).get_sequences() == result) + self.assertEqual(mailbox.MHMessage(msg).get_sequences(), result) msg = mailbox.BabylMessage(_sample_message) for label in ('unseen', 'deleted', 'filed', 'answered', 'forwarded', 'edited', 'resent'): msg.add_label(label) - self.assertTrue(mailbox.MHMessage(msg).get_sequences() == \ - ['unseen', 'replied']) + self.assertEqual(mailbox.MHMessage(msg).get_sequences(), + ['unseen', 'replied']) def test_babyl_to_babyl(self): # Convert BabylMessage to BabylMessage @@ -1581,12 +1584,12 @@ 'edited', 'resent'): msg.add_label(label) msg2 = mailbox.BabylMessage(msg) - self.assertTrue(msg2.get_labels() == ['unseen', 'deleted', 'filed', - 'answered', 'forwarded', 'edited', - 'resent']) - self.assertTrue(msg.get_visible().keys() == msg2.get_visible().keys()) + self.assertEqual(msg2.get_labels(), ['unseen', 'deleted', 'filed', + 'answered', 'forwarded', 'edited', + 'resent']) + self.assertEqual(msg.get_visible().keys(), msg2.get_visible().keys()) for key in msg.get_visible().keys(): - self.assertTrue(msg.get_visible()[key] == msg2.get_visible()[key]) + self.assertEqual(msg.get_visible()[key], msg2.get_visible()[key]) class TestProxyFileBase(TestBase): @@ -1594,69 +1597,66 @@ def _test_read(self, proxy): # Read by byte proxy.seek(0) - self.assertTrue(proxy.read() == 'bar') + self.assertEqual(proxy.read(), 'bar') proxy.seek(1) - self.assertTrue(proxy.read() == 'ar') + self.assertEqual(proxy.read(), 'ar') proxy.seek(0) - self.assertTrue(proxy.read(2) == 'ba') + self.assertEqual(proxy.read(2), 'ba') proxy.seek(1) - self.assertTrue(proxy.read(-1) == 'ar') + self.assertEqual(proxy.read(-1), 'ar') proxy.seek(2) - self.assertTrue(proxy.read(1000) == 'r') + self.assertEqual(proxy.read(1000), 'r') def _test_readline(self, proxy): # Read by line proxy.seek(0) - self.assertTrue(proxy.readline() == 'foo' + os.linesep) - self.assertTrue(proxy.readline() == 'bar' + os.linesep) - self.assertTrue(proxy.readline() == 'fred' + os.linesep) - self.assertTrue(proxy.readline() == 'bob') + self.assertEqual(proxy.readline(), 'foo' + os.linesep) + self.assertEqual(proxy.readline(), 'bar' + os.linesep) + self.assertEqual(proxy.readline(), 'fred' + os.linesep) + self.assertEqual(proxy.readline(), 'bob') proxy.seek(2) - self.assertTrue(proxy.readline() == 'o' + os.linesep) + self.assertEqual(proxy.readline(), 'o' + os.linesep) proxy.seek(6 + 2 * len(os.linesep)) - self.assertTrue(proxy.readline() == 'fred' + os.linesep) + self.assertEqual(proxy.readline(), 'fred' + os.linesep) proxy.seek(6 + 2 * len(os.linesep)) - self.assertTrue(proxy.readline(2) == 'fr') - self.assertTrue(proxy.readline(-10) == 'ed' + os.linesep) + self.assertEqual(proxy.readline(2), 'fr') + self.assertEqual(proxy.readline(-10), 'ed' + os.linesep) def _test_readlines(self, proxy): # Read multiple lines proxy.seek(0) - self.assertTrue(proxy.readlines() == ['foo' + os.linesep, - 'bar' + os.linesep, - 'fred' + os.linesep, 'bob']) + self.assertEqual(proxy.readlines(), ['foo' + os.linesep, + 'bar' + os.linesep, + 'fred' + os.linesep, 'bob']) proxy.seek(0) - self.assertTrue(proxy.readlines(2) == ['foo' + os.linesep]) + self.assertEqual(proxy.readlines(2), ['foo' + os.linesep]) proxy.seek(3 + len(os.linesep)) - self.assertTrue(proxy.readlines(4 + len(os.linesep)) == - ['bar' + os.linesep, 'fred' + os.linesep]) + self.assertEqual(proxy.readlines(4 + len(os.linesep)), + ['bar' + os.linesep, 'fred' + os.linesep]) proxy.seek(3) - self.assertTrue(proxy.readlines(1000) == [os.linesep, 'bar' + os.linesep, - 'fred' + os.linesep, 'bob']) + self.assertEqual(proxy.readlines(1000), [os.linesep, 'bar' + os.linesep, + 'fred' + os.linesep, 'bob']) def _test_iteration(self, proxy): # Iterate by line proxy.seek(0) iterator = iter(proxy) - self.assertTrue(iterator.next() == 'foo' + os.linesep) - self.assertTrue(iterator.next() == 'bar' + os.linesep) - self.assertTrue(iterator.next() == 'fred' + os.linesep) - self.assertTrue(iterator.next() == 'bob') - self.assertRaises(StopIteration, lambda: iterator.next()) + self.assertEqual(list(iterator), + ['foo' + os.linesep, 'bar' + os.linesep, 'fred' + os.linesep, 'bob']) def _test_seek_and_tell(self, proxy): # Seek and use tell to check position proxy.seek(3) - self.assertTrue(proxy.tell() == 3) - self.assertTrue(proxy.read(len(os.linesep)) == os.linesep) + self.assertEqual(proxy.tell(), 3) + self.assertEqual(proxy.read(len(os.linesep)), os.linesep) proxy.seek(2, 1) - self.assertTrue(proxy.read(1 + len(os.linesep)) == 'r' + os.linesep) + self.assertEqual(proxy.read(1 + len(os.linesep)), 'r' + os.linesep) proxy.seek(-3 - len(os.linesep), 2) - self.assertTrue(proxy.read(3) == 'bar') + self.assertEqual(proxy.read(3), 'bar') proxy.seek(2, 0) - self.assertTrue(proxy.read() == 'o' + os.linesep + 'bar' + os.linesep) + self.assertEqual(proxy.read(), 'o' + os.linesep + 'bar' + os.linesep) proxy.seek(100) - self.assertTrue(proxy.read() == '') + self.assertEqual(proxy.read(), '') def _test_close(self, proxy): # Close a file @@ -1679,11 +1679,11 @@ self._file.write('foo') pos = self._file.tell() proxy0 = mailbox._ProxyFile(self._file) - self.assertTrue(proxy0.tell() == pos) - self.assertTrue(self._file.tell() == pos) + self.assertEqual(proxy0.tell(), pos) + self.assertEqual(self._file.tell(), pos) proxy1 = mailbox._ProxyFile(self._file, 0) - self.assertTrue(proxy1.tell() == 0) - self.assertTrue(self._file.tell() == pos) + self.assertEqual(proxy1.tell(), 0) + self.assertEqual(self._file.tell(), pos) def test_read(self): self._file.write('bar') @@ -1728,8 +1728,8 @@ self._file.write('foo' + os.linesep + 'bar') pos = self._file.tell() proxy = mailbox._PartialFile(self._file, 2, 5) - self.assertTrue(proxy.tell() == 0) - self.assertTrue(self._file.tell() == pos) + self.assertEqual(proxy.tell(), 0) + self.assertEqual(self._file.tell(), pos) def test_read(self): self._file.write('***bar***') @@ -1823,34 +1823,34 @@ self.mbox = mailbox.Maildir(test_support.TESTFN) #self.assertTrue(hasattr(self.mbox, "boxes")) #self.assertTrue(len(self.mbox.boxes) == 0) - self.assertTrue(self.mbox.next() is None) - self.assertTrue(self.mbox.next() is None) + self.assertIs(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) def test_nonempty_maildir_cur(self): self.createMessage("cur") self.mbox = mailbox.Maildir(test_support.TESTFN) #self.assertTrue(len(self.mbox.boxes) == 1) - self.assertTrue(self.mbox.next() is not None) - self.assertTrue(self.mbox.next() is None) - self.assertTrue(self.mbox.next() is None) + self.assertIsNot(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) def test_nonempty_maildir_new(self): self.createMessage("new") self.mbox = mailbox.Maildir(test_support.TESTFN) #self.assertTrue(len(self.mbox.boxes) == 1) - self.assertTrue(self.mbox.next() is not None) - self.assertTrue(self.mbox.next() is None) - self.assertTrue(self.mbox.next() is None) + self.assertIsNot(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) def test_nonempty_maildir_both(self): self.createMessage("cur") self.createMessage("new") self.mbox = mailbox.Maildir(test_support.TESTFN) #self.assertTrue(len(self.mbox.boxes) == 2) - self.assertTrue(self.mbox.next() is not None) - self.assertTrue(self.mbox.next() is not None) - self.assertTrue(self.mbox.next() is None) - self.assertTrue(self.mbox.next() is None) + self.assertIsNot(self.mbox.next(), None) + self.assertIsNot(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) + self.assertIs(self.mbox.next(), None) def test_unix_mbox(self): ### should be better! From python-checkins at python.org Sun Nov 1 00:26:47 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 31 Oct 2009 23:26:47 -0000 Subject: [Python-checkins] r76002 - python/branches/py3k Message-ID: Author: antoine.pitrou Date: Sun Nov 1 00:26:47 2009 New Revision: 76002 Log: Blocked revisions 76001 via svnmerge Apparently someone already did the job in py3k. ........ r76001 | antoine.pitrou | 2009-11-01 00:19:52 +0100 (dim., 01 nov. 2009) | 3 lines Use richer assertions in test_mailbox (for better failure messages). ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Nov 1 01:30:13 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 00:30:13 -0000 Subject: [Python-checkins] r76003 - python/trunk/Lib/mailbox.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 01:30:13 2009 New Revision: 76003 Log: Hopefully fix the buildbot problems on test_mailbox, by computing the maildir toc cache refresh date before actually refreshing the cache. (see #6896) Modified: python/trunk/Lib/mailbox.py Modified: python/trunk/Lib/mailbox.py ============================================================================== --- python/trunk/Lib/mailbox.py (original) +++ python/trunk/Lib/mailbox.py Sun Nov 1 01:30:13 2009 @@ -462,12 +462,21 @@ def _refresh(self): """Update table of contents mapping.""" - new_mtime = os.path.getmtime(os.path.join(self._path, 'new')) - cur_mtime = os.path.getmtime(os.path.join(self._path, 'cur')) + if self._last_read is not None: + for subdir in ('new', 'cur'): + mtime = os.path.getmtime(os.path.join(self._path, subdir)) + if mtime > self._last_read: + break + else: + return - if (self._last_read is not None and - new_mtime <= self._last_read and cur_mtime <= self._last_read): - return + # We record the current time - 1sec so that, if _refresh() is called + # again in the same second, we will always re-read the mailbox + # just in case it's been modified. (os.path.mtime() only has + # 1sec resolution.) This results in a few unnecessary re-reads + # when _refresh() is called multiple times in the same second, + # but once the clock ticks over, we will only re-read as needed. + now = time.time() - 1 self._toc = {} def update_dir (subdir): @@ -482,14 +491,7 @@ update_dir('new') update_dir('cur') - # We record the current time - 1sec so that, if _refresh() is called - # again in the same second, we will always re-read the mailbox - # just in case it's been modified. (os.path.mtime() only has - # 1sec resolution.) This results in a few unnecessary re-reads - # when _refresh() is called multiple times in the same second, - # but once the clock ticks over, we will only re-read as needed. - now = int(time.time() - 1) - self._last_read = time.time() - 1 + self._last_read = now def _lookup(self, key): """Use TOC to return subpath for given key, or raise a KeyError.""" From python-checkins at python.org Sun Nov 1 09:53:21 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 01 Nov 2009 08:53:21 -0000 Subject: [Python-checkins] r76004 - in python/branches/release26-maint: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Sun Nov 1 09:53:21 2009 New Revision: 76004 Log: Issue 7244: fix exception handling in itertools.izip_longest(). Modified: python/branches/release26-maint/Lib/test/test_itertools.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/itertoolsmodule.c Modified: python/branches/release26-maint/Lib/test/test_itertools.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_itertools.py (original) +++ python/branches/release26-maint/Lib/test/test_itertools.py Sun Nov 1 09:53:21 2009 @@ -398,6 +398,42 @@ ids = map(id, list(izip_longest('abc', 'def'))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_bug_7244(self): + + class Repeater(object): + # this class is similar to itertools.repeat + def __init__(self, o, t, e): + self.o = o + self.t = int(t) + self.e = e + def __iter__(self): # its iterator is itself + return self + def next(self): + if self.t > 0: + self.t -= 1 + return self.o + else: + raise self.e + + # Formerly this code in would fail in debug mode + # with Undetected Error and Stop Iteration + r1 = Repeater(1, 3, StopIteration) + r2 = Repeater(2, 4, StopIteration) + def run(r1, r2): + result = [] + for i, j in izip_longest(r1, r2, fillvalue=0): + print(i, j) + result.append((i, j)) + return result + self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) + + # Formerly, the RuntimeError would be lost + # and StopIteration would stop as expected + r1 = Repeater(1, 3, RuntimeError) + r2 = Repeater(2, 4, StopIteration) + mylist = lambda it: [v for v in it] + self.assertRaises(RuntimeError, mylist, izip_longest(r1, r2, fillvalue=0)) + def test_product(self): for args, result in [ ([], [()]), # zero iterables @@ -687,6 +723,7 @@ self.assertRaises(StopIteration, f(lambda x:x, []).next) self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next) + class TestExamples(unittest.TestCase): def test_chain(self): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Nov 1 09:53:21 2009 @@ -24,6 +24,9 @@ Library ------- +- Issue #7244: itertools.izip_longest() no longer ignores exceptions + raised during the formation of an output tuple. + - Issue #7233: Fix a number of two-argument Decimal methods to make sure that they accept an int or long as the second argument. Also fix buggy handling of large arguments (those with coefficient longer Modified: python/branches/release26-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release26-maint/Modules/itertoolsmodule.c Sun Nov 1 09:53:21 2009 @@ -3412,10 +3412,11 @@ item = lz->fillvalue; } else { assert(PyIter_Check(it)); - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { @@ -3441,10 +3442,11 @@ item = lz->fillvalue; } else { assert(PyIter_Check(it)); - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { lz->numactive -= 1; - if (lz->numactive == 0) { + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { From solipsis at pitrou.net Sun Nov 1 12:16:07 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Sun, 1 Nov 2009 11:16:07 +0000 (UTC) Subject: [Python-checkins] =?utf-8?q?r76004_-_in_python/branches/release26?= =?utf-8?q?-maint=3A=09Lib/test/test=5Fitertools=2Epy_Misc/NEWS_Mod?= =?utf-8?q?ules/itertoolsmodule=2Ec?= References: <38492.2136007392$1257065619@news.gmane.org> Message-ID: writes: > > Log: > Issue 7244: fix exception handling in itertools.izip_longest(). The "print"s make the buildbots fail with the message "unexpected output". Regards Antoine. From python-checkins at python.org Sun Nov 1 12:17:38 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 11:17:38 -0000 Subject: [Python-checkins] r76005 - in sandbox/trunk/newgil: Doc/c-api/conversion.rst Doc/library/logging.rst Lib/decimal.py Lib/gzip.py Lib/test/decimaltestdata/extra.decTest Lib/test/regrtest.py Lib/test/support.py Lib/test/test_ascii_formatd.py Lib/test/test_asynchat.py Lib/test/test_decimal.py Lib/test/test_docxmlrpc.py Lib/test/test_pep263.py Lib/test/test_pydoc.py Lib/test/test_signal.py Lib/test/test_thread.py Lib/test/test_xmlrpc.py Misc/NEWS Modules/_io/_iomodule.h Modules/_io/bufferedio.c Modules/_threadmodule.c Python/ast.c Python/ceval.c Message-ID: Author: antoine.pitrou Date: Sun Nov 1 12:17:37 2009 New Revision: 76005 Log: Merged revisions 75922,75928-75929,75932,75937,75941,75947,75959,75961,75964-75966,75968,75970,75976-75977,75981,75984,75988,75992,75997,76002 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r75922 | r.david.murray | 2009-10-28 15:07:51 +0100 (mer., 28 oct. 2009) | 9 lines Merged revisions 75920 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75920 | r.david.murray | 2009-10-28 10:03:43 -0400 (Wed, 28 Oct 2009) | 2 lines Remove variable that is no longer used. ........ ................ r75928 | benjamin.peterson | 2009-10-28 22:59:39 +0100 (mer., 28 oct. 2009) | 5 lines in wide builds, avoid storing high unicode characters from source code with surrogates This is accomplished by decoding with utf-32 instead of utf-16 on all builds. The patch is by Adam Olsen. ................ r75929 | vinay.sajip | 2009-10-29 00:28:16 +0100 (jeu., 29 oct. 2009) | 1 line Issue 7199: Documentation made slightly more consistent w.r.t. logging level enumeration. ................ r75932 | benjamin.peterson | 2009-10-29 02:50:06 +0100 (jeu., 29 oct. 2009) | 11 lines Blocked revisions 75931 via svnmerge ........ r75931 | benjamin.peterson | 2009-10-28 20:49:07 -0500 (Wed, 28 Oct 2009) | 5 lines do a backport of r75928 The added test does not fail without the patch, but we still fix the issue of surrogates being used in wide builds where they should not be. ........ ................ r75937 | lars.gustaebel | 2009-10-29 10:39:47 +0100 (jeu., 29 oct. 2009) | 10 lines Merged revisions 75935 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75935 | lars.gustaebel | 2009-10-29 10:15:00 +0100 (Thu, 29 Oct 2009) | 3 lines Issue #4750: Store the basename of the original filename in the gzip FNAME header as required by RFC 1952. ........ ................ r75941 | mark.dickinson | 2009-10-29 10:58:06 +0100 (jeu., 29 oct. 2009) | 11 lines Merged revisions 75939 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75939 | mark.dickinson | 2009-10-29 09:46:04 +0000 (Thu, 29 Oct 2009) | 5 lines Roll back ill-considered attempts to fix printf specifier mismatch for off_t. The sensible solution seems to be to implement %lld for PyString_FromFormat(V) and PyErr_Format. See issue #7228. ........ ................ r75947 | mark.dickinson | 2009-10-29 13:23:02 +0100 (jeu., 29 oct. 2009) | 20 lines Merged revisions 75943-75945 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75943 | mark.dickinson | 2009-10-29 11:09:09 +0000 (Thu, 29 Oct 2009) | 1 line Fix duplicate test numbers in extra.decTest ........ r75944 | mark.dickinson | 2009-10-29 12:04:00 +0000 (Thu, 29 Oct 2009) | 3 lines Issue #7233: A number of two-argument Decimal methods were failing to accept ints and longs for the second argument. ........ r75945 | mark.dickinson | 2009-10-29 12:11:18 +0000 (Thu, 29 Oct 2009) | 4 lines Issue #7233: Fix Decimal.shift and Decimal.rotate methods for arguments with more digits than the current context precision. Bug reported by Stefan Krah. ........ ................ r75959 | antoine.pitrou | 2009-10-30 18:25:12 +0100 (ven., 30 oct. 2009) | 13 lines Merged revisions 75958 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75958 | antoine.pitrou | 2009-10-30 18:07:08 +0100 (ven., 30 oct. 2009) | 7 lines Issue #7222: Make thread "reaping" more reliable so that reference leak-chasing test runs give sensible results. The previous method of reaping threads could return successfully while some Thread objects were still referenced. This also introduces a new private function: :func:hread._count(). ........ ................ r75961 | antoine.pitrou | 2009-10-30 18:34:49 +0100 (ven., 30 oct. 2009) | 9 lines Merged revisions 75960 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75960 | antoine.pitrou | 2009-10-30 18:33:28 +0100 (ven., 30 oct. 2009) | 3 lines Fix transient refleaks in test_docxmlrpc. ........ ................ r75964 | antoine.pitrou | 2009-10-30 18:58:27 +0100 (ven., 30 oct. 2009) | 13 lines Merged revisions 75962-75963 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75962 | antoine.pitrou | 2009-10-30 18:55:21 +0100 (ven., 30 oct. 2009) | 3 lines Try to fix transient refleaks in test_asynchat. ........ r75963 | antoine.pitrou | 2009-10-30 18:56:00 +0100 (ven., 30 oct. 2009) | 3 lines Try to fix transient refleaks in test_xmlrpc. ........ ................ r75965 | antoine.pitrou | 2009-10-30 19:15:02 +0100 (ven., 30 oct. 2009) | 5 lines Fix a refleak in test_uuid when run with -j. The "refleak" was simply the effect of internal buffering in block buffering mode (rather than line buffering when sys.stdout is a terminal) ................ r75966 | antoine.pitrou | 2009-10-30 19:30:35 +0100 (ven., 30 oct. 2009) | 4 lines Followup to r75965: replace the test_uuid-specific patch with a generic fix (other tests may have the same problem). ................ r75968 | antoine.pitrou | 2009-10-30 22:45:40 +0100 (ven., 30 oct. 2009) | 9 lines Merged revisions 75967 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75967 | antoine.pitrou | 2009-10-30 22:41:22 +0100 (ven., 30 oct. 2009) | 3 lines Try to fix transient refleaks in test_pydoc. ........ ................ r75970 | antoine.pitrou | 2009-10-30 23:23:02 +0100 (ven., 30 oct. 2009) | 10 lines Merged revisions 75969 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75969 | antoine.pitrou | 2009-10-30 23:19:09 +0100 (ven., 30 oct. 2009) | 5 lines Remove official documentation entry for thread._count() and make the docstring more descriptive instead. ........ ................ r75976 | mark.dickinson | 2009-10-31 10:29:47 +0100 (sam., 31 oct. 2009) | 8 lines Blocked revisions 75974 via svnmerge ........ r75974 | mark.dickinson | 2009-10-31 09:28:12 +0000 (Sat, 31 Oct 2009) | 1 line Move a Misc/NEWS entry to right section. ........ ................ r75977 | mark.dickinson | 2009-10-31 10:39:52 +0100 (sam., 31 oct. 2009) | 1 line Fix ReST markup. ................ r75981 | mark.dickinson | 2009-10-31 10:43:46 +0100 (sam., 31 oct. 2009) | 8 lines Blocked revisions 75979 via svnmerge ........ r75979 | mark.dickinson | 2009-10-31 09:42:39 +0000 (Sat, 31 Oct 2009) | 1 line Deprecate PyOS_ascii_strtod and PyOS_ascii_atof, and document the replacement function PyOS_string_to_double. ........ ................ r75984 | mark.dickinson | 2009-10-31 11:18:44 +0100 (sam., 31 oct. 2009) | 12 lines Merged revisions 75982 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75982 | mark.dickinson | 2009-10-31 10:11:28 +0000 (Sat, 31 Oct 2009) | 5 lines Issue #6603: Fix --with-tsc build failures on x86-64 that resulted from a gcc inline assembler peculiarity. (gcc's "A" constraint apparently means 'rax or rdx' in 64-bit mode, not edx:eax or rdx:rax as one might expect.) ........ ................ r75988 | mark.dickinson | 2009-10-31 11:38:43 +0100 (sam., 31 oct. 2009) | 9 lines Merged revisions 75986 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75986 | mark.dickinson | 2009-10-31 10:36:06 +0000 (Sat, 31 Oct 2009) | 2 lines Issue #7042: Use a better mechanism for testing timers in test_signal. ........ ................ r75992 | mark.dickinson | 2009-10-31 13:48:28 +0100 (sam., 31 oct. 2009) | 8 lines Blocked revisions 75991 via svnmerge ........ r75991 | mark.dickinson | 2009-10-31 12:47:47 +0000 (Sat, 31 Oct 2009) | 1 line Set retval on PyOS_string_to_double failure. ........ ................ r75997 | eric.smith | 2009-10-31 18:08:48 +0100 (sam., 31 oct. 2009) | 9 lines Merged revisions 75995 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75995 | eric.smith | 2009-10-31 13:07:17 -0400 (Sat, 31 Oct 2009) | 1 line Improved test for a deprecation warning. ........ ................ r76002 | antoine.pitrou | 2009-11-01 00:26:47 +0100 (dim., 01 nov. 2009) | 9 lines Blocked revisions 76001 via svnmerge Apparently someone already did the job in py3k. ........ r76001 | antoine.pitrou | 2009-11-01 00:19:52 +0100 (dim., 01 nov. 2009) | 3 lines Use richer assertions in test_mailbox (for better failure messages). ........ ................ Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Doc/c-api/conversion.rst sandbox/trunk/newgil/Doc/library/logging.rst sandbox/trunk/newgil/Lib/decimal.py sandbox/trunk/newgil/Lib/gzip.py sandbox/trunk/newgil/Lib/test/decimaltestdata/extra.decTest sandbox/trunk/newgil/Lib/test/regrtest.py sandbox/trunk/newgil/Lib/test/support.py sandbox/trunk/newgil/Lib/test/test_ascii_formatd.py sandbox/trunk/newgil/Lib/test/test_asynchat.py sandbox/trunk/newgil/Lib/test/test_decimal.py sandbox/trunk/newgil/Lib/test/test_docxmlrpc.py sandbox/trunk/newgil/Lib/test/test_pep263.py sandbox/trunk/newgil/Lib/test/test_pydoc.py sandbox/trunk/newgil/Lib/test/test_signal.py sandbox/trunk/newgil/Lib/test/test_thread.py sandbox/trunk/newgil/Lib/test/test_xmlrpc.py sandbox/trunk/newgil/Misc/NEWS sandbox/trunk/newgil/Modules/_io/_iomodule.h sandbox/trunk/newgil/Modules/_io/bufferedio.c sandbox/trunk/newgil/Modules/_threadmodule.c sandbox/trunk/newgil/Python/ast.c sandbox/trunk/newgil/Python/ceval.c Modified: sandbox/trunk/newgil/Doc/c-api/conversion.rst ============================================================================== --- sandbox/trunk/newgil/Doc/c-api/conversion.rst (original) +++ sandbox/trunk/newgil/Doc/c-api/conversion.rst Sun Nov 1 12:17:37 2009 @@ -155,7 +155,7 @@ See the Unix man page :manpage:`atof(2)` for details. .. deprecated:: 3.1 - Use PyOS_string_to_double instead. + Use :cfunc:`PyOS_string_to_double` instead. .. cfunction:: char* PyOS_stricmp(char *s1, char *s2) Modified: sandbox/trunk/newgil/Doc/library/logging.rst ============================================================================== --- sandbox/trunk/newgil/Doc/library/logging.rst (original) +++ sandbox/trunk/newgil/Doc/library/logging.rst Sun Nov 1 12:17:37 2009 @@ -119,7 +119,7 @@ messages at different log levels. This allows you to instrument your code with debug messages, for example, but turning the log level down so that those debug messages are not written for your production system. The default levels are -``CRITICAL``, ``ERROR``, ``WARNING``, ``INFO``, ``DEBUG`` and ``NOTSET``. +``NOTSET``, ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` and ``CRITICAL``. The logger, handler, and log message call each specify a level. The log message is only emitted if the handler and logger are configured to emit messages of Modified: sandbox/trunk/newgil/Lib/decimal.py ============================================================================== --- sandbox/trunk/newgil/Lib/decimal.py (original) +++ sandbox/trunk/newgil/Lib/decimal.py Sun Nov 1 12:17:37 2009 @@ -2806,6 +2806,8 @@ value. Note that a total ordering is defined for all possible abstract representations. """ + other = _convert_other(other, raiseit=True) + # if one is negative and the other is positive, it's easy if self._sign and not other._sign: return _NegativeOne @@ -2875,6 +2877,8 @@ Like compare_total, but with operand's sign ignored and assumed to be 0. """ + other = _convert_other(other, raiseit=True) + s = self.copy_abs() o = other.copy_abs() return s.compare_total(o) @@ -3243,6 +3247,9 @@ """Applies an 'and' operation between self and other's digits.""" if context is None: context = getcontext() + + other = _convert_other(other, raiseit=True) + if not self._islogical() or not other._islogical(): return context._raise_error(InvalidOperation) @@ -3264,6 +3271,9 @@ """Applies an 'or' operation between self and other's digits.""" if context is None: context = getcontext() + + other = _convert_other(other, raiseit=True) + if not self._islogical() or not other._islogical(): return context._raise_error(InvalidOperation) @@ -3278,6 +3288,9 @@ """Applies an 'xor' operation between self and other's digits.""" if context is None: context = getcontext() + + other = _convert_other(other, raiseit=True) + if not self._islogical() or not other._islogical(): return context._raise_error(InvalidOperation) @@ -3491,6 +3504,8 @@ if context is None: context = getcontext() + other = _convert_other(other, raiseit=True) + ans = self._check_nans(other, context) if ans: return ans @@ -3507,19 +3522,23 @@ torot = int(other) rotdig = self._int topad = context.prec - len(rotdig) - if topad: + if topad > 0: rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] # let's rotate! rotated = rotdig[torot:] + rotdig[:torot] return _dec_from_triple(self._sign, rotated.lstrip('0') or '0', self._exp) - def scaleb (self, other, context=None): + def scaleb(self, other, context=None): """Returns self operand after adding the second value to its exp.""" if context is None: context = getcontext() + other = _convert_other(other, raiseit=True) + ans = self._check_nans(other, context) if ans: return ans @@ -3543,6 +3562,8 @@ if context is None: context = getcontext() + other = _convert_other(other, raiseit=True) + ans = self._check_nans(other, context) if ans: return ans @@ -3557,22 +3578,22 @@ # get values, pad if necessary torot = int(other) - if not torot: - return Decimal(self) rotdig = self._int topad = context.prec - len(rotdig) - if topad: + if topad > 0: rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] # let's shift! if torot < 0: - rotated = rotdig[:torot] + shifted = rotdig[:torot] else: - rotated = rotdig + '0'*torot - rotated = rotated[-context.prec:] + shifted = rotdig + '0'*torot + shifted = shifted[-context.prec:] return _dec_from_triple(self._sign, - rotated.lstrip('0') or '0', self._exp) + shifted.lstrip('0') or '0', self._exp) # Support for pickling, copy, and deepcopy def __reduce__(self): Modified: sandbox/trunk/newgil/Lib/gzip.py ============================================================================== --- sandbox/trunk/newgil/Lib/gzip.py (original) +++ sandbox/trunk/newgil/Lib/gzip.py Sun Nov 1 12:17:37 2009 @@ -5,7 +5,7 @@ # based on Andrew Kuchling's minigzip.py distributed with the zlib module -import struct, sys, time +import struct, sys, time, os import zlib import builtins @@ -158,7 +158,8 @@ try: # RFC 1952 requires the FNAME field to be Latin-1. Do not # include filenames that cannot be represented that way. - fname = self.name.encode('latin-1') + fname = os.path.basename(self.name) + fname = fname.encode('latin-1') if fname.endswith(b'.gz'): fname = fname[:-3] except UnicodeEncodeError: Modified: sandbox/trunk/newgil/Lib/test/decimaltestdata/extra.decTest ============================================================================== --- sandbox/trunk/newgil/Lib/test/decimaltestdata/extra.decTest (original) +++ sandbox/trunk/newgil/Lib/test/decimaltestdata/extra.decTest Sun Nov 1 12:17:37 2009 @@ -154,22 +154,6 @@ extr1302 fma 0E123 -Inf sNaN789 -> NaN Invalid_operation extr1302 fma -Inf 0E-456 sNaN148 -> NaN Invalid_operation --- Issue #6794: when comparing NaNs using compare_total, payloads --- should be compared as though positive integers; not --- lexicographically as strings. -extr1400 comparetotal NaN123 NaN45 -> 1 -extr1401 comparetotal sNaN123 sNaN45 -> 1 -extr1402 comparetotal -NaN123 -NaN45 -> -1 -extr1403 comparetotal -sNaN123 -sNaN45 -> -1 -extr1404 comparetotal NaN45 NaN123 -> -1 -extr1405 comparetotal sNaN45 sNaN123 -> -1 -extr1406 comparetotal -NaN45 -NaN123 -> 1 -extr1407 comparetotal -sNaN45 -sNaN123 -> 1 - -extr1410 comparetotal -sNaN63450748854172416 -sNaN911993 -> -1 -extr1411 comparetotmag NaN1222222222222 -NaN999999 -> 1 - - -- max/min/max_mag/min_mag bug in 2.5.2/2.6/3.0: max(NaN, finite) gave -- incorrect answers when the finite number required rounding; similarly -- for the other thre functions @@ -187,6 +171,50 @@ extr1430 min_mag 9181716151 -NaN -> 9.18172E+9 Inexact Rounded extr1431 min_mag NaN4 1.818180E100 -> 1.81818E+100 Rounded +-- Issue #6794: when comparing NaNs using compare_total, payloads +-- should be compared as though positive integers; not +-- lexicographically as strings. +extr1500 comparetotal NaN123 NaN45 -> 1 +extr1501 comparetotal sNaN123 sNaN45 -> 1 +extr1502 comparetotal -NaN123 -NaN45 -> -1 +extr1503 comparetotal -sNaN123 -sNaN45 -> -1 +extr1504 comparetotal NaN45 NaN123 -> -1 +extr1505 comparetotal sNaN45 sNaN123 -> -1 +extr1506 comparetotal -NaN45 -NaN123 -> 1 +extr1507 comparetotal -sNaN45 -sNaN123 -> 1 + +extr1510 comparetotal -sNaN63450748854172416 -sNaN911993 -> -1 +extr1511 comparetotmag NaN1222222222222 -NaN999999 -> 1 + +-- Issue #7233: rotate and scale should truncate an argument +-- of length greater than the current precision. +precision: 4 +extr1600 rotate 1234567 -5 -> NaN Invalid_operation +extr1601 rotate 1234567 -4 -> 4567 +extr1602 rotate 1234567 -3 -> 5674 +extr1603 rotate 1234567 -2 -> 6745 +extr1604 rotate 1234567 -1 -> 7456 +extr1605 rotate 1234567 0 -> 4567 +extr1606 rotate 1234567 1 -> 5674 +extr1607 rotate 1234567 2 -> 6745 +extr1608 rotate 1234567 3 -> 7456 +extr1609 rotate 1234567 4 -> 4567 +extr1610 rotate 1234567 5 -> NaN Invalid_operation + +extr1650 shift 1234567 -5 -> NaN Invalid_operation +extr1651 shift 1234567 -4 -> 0 +extr1652 shift 1234567 -3 -> 4 +extr1653 shift 1234567 -2 -> 45 +extr1654 shift 1234567 -1 -> 456 +extr1655 shift 1234567 0 -> 4567 +extr1656 shift 1234567 1 -> 5670 +extr1657 shift 1234567 2 -> 6700 +extr1658 shift 1234567 3 -> 7000 +extr1659 shift 1234567 4 -> 0 +extr1660 shift 1234567 5 -> NaN Invalid_operation + + + -- Tests for the is_* boolean operations precision: 9 maxExponent: 999 Modified: sandbox/trunk/newgil/Lib/test/regrtest.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/regrtest.py (original) +++ sandbox/trunk/newgil/Lib/test/regrtest.py Sun Nov 1 12:17:37 2009 @@ -996,6 +996,12 @@ obj._abc_cache.clear() obj._abc_negative_cache.clear() + # Flush standard output, so that buffered data is sent to the OS and + # associated Python objects are reclaimed. + for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): + if stream is not None: + stream.flush() + # Clear assorted module caches. _path_created.clear() re.purge() @@ -1368,7 +1374,7 @@ # much of the testing framework relies on the globals in the # test.support module. mydir = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0]))) - i = pathlen = len(sys.path) + i = len(sys.path) while i >= 0: i -= 1 if os.path.abspath(os.path.normpath(sys.path[i])) == mydir: Modified: sandbox/trunk/newgil/Lib/test/support.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/support.py (original) +++ sandbox/trunk/newgil/Lib/test/support.py Sun Nov 1 12:17:37 2009 @@ -947,24 +947,29 @@ #======================================================================= # Threading support to prevent reporting refleaks when running regrtest.py -R +# NOTE: we use thread._count() rather than threading.enumerate() (or the +# moral equivalent thereof) because a threading.Thread object is still alive +# until its __bootstrap() method has returned, even after it has been +# unregistered from the threading module. +# thread._count(), on the other hand, only gets decremented *after* the +# __bootstrap() method has returned, which gives us reliable reference counts +# at the end of a test run. + def threading_setup(): - import threading - return len(threading._active), len(threading._limbo) + import _thread + return _thread._count(), -def threading_cleanup(num_active, num_limbo): - import threading +def threading_cleanup(nb_threads): + import _thread import time _MAX_COUNT = 10 - count = 0 - while len(threading._active) != num_active and count < _MAX_COUNT: - count += 1 - time.sleep(0.1) - - count = 0 - while len(threading._limbo) != num_limbo and count < _MAX_COUNT: - count += 1 + for count in range(_MAX_COUNT): + n = _thread._count() + if n == nb_threads: + break time.sleep(0.1) + # XXX print a warning in case of failure? def reap_threads(func): @functools.wraps(func) Modified: sandbox/trunk/newgil/Lib/test/test_ascii_formatd.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_ascii_formatd.py (original) +++ sandbox/trunk/newgil/Lib/test/test_ascii_formatd.py Sun Nov 1 12:17:37 2009 @@ -20,8 +20,7 @@ c_double(10.0)) self.assertEqual(buf.value, b'+10.0000000000') - self.assertEqual(str(w.message), 'PyOS_ascii_formatd is deprecated, ' - 'use PyOS_double_to_string instead') + self.assertEqual(w.category, DeprecationWarning) class FormatTests(unittest.TestCase): # ensure that, for the restricted set of format codes, Modified: sandbox/trunk/newgil/Lib/test/test_asynchat.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_asynchat.py (original) +++ sandbox/trunk/newgil/Lib/test/test_asynchat.py Sun Nov 1 12:17:37 2009 @@ -93,10 +93,10 @@ usepoll = False def setUp (self): - pass + self._threads = support.threading_setup() def tearDown (self): - pass + support.threading_cleanup(*self._threads) def line_terminator_check(self, term, server_chunk): event = threading.Event() Modified: sandbox/trunk/newgil/Lib/test/test_decimal.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_decimal.py (original) +++ sandbox/trunk/newgil/Lib/test/test_decimal.py Sun Nov 1 12:17:37 2009 @@ -1530,6 +1530,53 @@ self.assertEqual(str(Decimal(0).sqrt()), str(c.sqrt(Decimal(0)))) + def test_conversions_from_int(self): + # Check that methods taking a second Decimal argument will + # always accept an integer in place of a Decimal. + self.assertEqual(Decimal(4).compare(3), + Decimal(4).compare(Decimal(3))) + self.assertEqual(Decimal(4).compare_signal(3), + Decimal(4).compare_signal(Decimal(3))) + self.assertEqual(Decimal(4).compare_total(3), + Decimal(4).compare_total(Decimal(3))) + self.assertEqual(Decimal(4).compare_total_mag(3), + Decimal(4).compare_total_mag(Decimal(3))) + self.assertEqual(Decimal(10101).logical_and(1001), + Decimal(10101).logical_and(Decimal(1001))) + self.assertEqual(Decimal(10101).logical_or(1001), + Decimal(10101).logical_or(Decimal(1001))) + self.assertEqual(Decimal(10101).logical_xor(1001), + Decimal(10101).logical_xor(Decimal(1001))) + self.assertEqual(Decimal(567).max(123), + Decimal(567).max(Decimal(123))) + self.assertEqual(Decimal(567).max_mag(123), + Decimal(567).max_mag(Decimal(123))) + self.assertEqual(Decimal(567).min(123), + Decimal(567).min(Decimal(123))) + self.assertEqual(Decimal(567).min_mag(123), + Decimal(567).min_mag(Decimal(123))) + self.assertEqual(Decimal(567).next_toward(123), + Decimal(567).next_toward(Decimal(123))) + self.assertEqual(Decimal(1234).quantize(100), + Decimal(1234).quantize(Decimal(100))) + self.assertEqual(Decimal(768).remainder_near(1234), + Decimal(768).remainder_near(Decimal(1234))) + self.assertEqual(Decimal(123).rotate(1), + Decimal(123).rotate(Decimal(1))) + self.assertEqual(Decimal(1234).same_quantum(1000), + Decimal(1234).same_quantum(Decimal(1000))) + self.assertEqual(Decimal('9.123').scaleb(-100), + Decimal('9.123').scaleb(Decimal(-100))) + self.assertEqual(Decimal(456).shift(-1), + Decimal(456).shift(Decimal(-1))) + + self.assertEqual(Decimal(-12).fma(Decimal(45), 67), + Decimal(-12).fma(Decimal(45), Decimal(67))) + self.assertEqual(Decimal(-12).fma(45, 67), + Decimal(-12).fma(Decimal(45), Decimal(67))) + self.assertEqual(Decimal(-12).fma(45, Decimal(67)), + Decimal(-12).fma(Decimal(45), Decimal(67))) + class DecimalPythonAPItests(unittest.TestCase): Modified: sandbox/trunk/newgil/Lib/test/test_docxmlrpc.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_docxmlrpc.py (original) +++ sandbox/trunk/newgil/Lib/test/test_docxmlrpc.py Sun Nov 1 12:17:37 2009 @@ -53,6 +53,7 @@ class DocXMLRPCHTTPGETServer(unittest.TestCase): def setUp(self): + self._threads = support.threading_setup() # Enable server feedback DocXMLRPCServer._send_traceback_header = True @@ -74,6 +75,7 @@ # Disable server feedback DocXMLRPCServer._send_traceback_header = False + support.threading_cleanup(*self._threads) def test_valid_get_response(self): self.client.request("GET", "/") Modified: sandbox/trunk/newgil/Lib/test/test_pep263.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_pep263.py (original) +++ sandbox/trunk/newgil/Lib/test/test_pep263.py Sun Nov 1 12:17:37 2009 @@ -36,6 +36,14 @@ exec(c, d) self.assertEquals(d['\xc6'], '\xc6') + def test_issue3297(self): + c = compile("a, b = '\U0001010F', '\\U0001010F'", "dummy", "exec") + d = {} + exec(c, d) + self.assertEqual(d['a'], d['b']) + self.assertEqual(len(d['a']), len(d['b'])) + self.assertEqual(ascii(d['a']), ascii(d['b'])) + def test_main(): support.run_unittest(PEP263Test) Modified: sandbox/trunk/newgil/Lib/test/test_pydoc.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_pydoc.py (original) +++ sandbox/trunk/newgil/Lib/test/test_pydoc.py Sun Nov 1 12:17:37 2009 @@ -9,7 +9,8 @@ import unittest import test.support from contextlib import contextmanager -from test.support import TESTFN, forget, rmtree, EnvironmentVarGuard +from test.support import ( + TESTFN, forget, rmtree, EnvironmentVarGuard, reap_children) from test import pydoc_mod @@ -195,8 +196,11 @@ output of pydoc. """ cmd = [sys.executable, pydoc.__file__, " ".join(args), module_name] - output = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout.read() - return output.strip() + try: + output = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0] + return output.strip() + finally: + reap_children() def get_pydoc_html(module): "Returns pydoc generated output as html" Modified: sandbox/trunk/newgil/Lib/test/test_signal.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_signal.py (original) +++ sandbox/trunk/newgil/Lib/test/test_signal.py Sun Nov 1 12:17:37 2009 @@ -360,11 +360,14 @@ signal.signal(signal.SIGVTALRM, self.sig_vtalrm) signal.setitimer(self.itimer, 0.3, 0.2) - for i in range(100000000): + start_time = time.time() + while time.time() - start_time < 5.0: # use up some virtual time by doing real work _ = pow(12345, 67890, 10000019) if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_vtalrm handler stopped this itimer + else: + self.fail('timeout waiting for sig_vtalrm signal') # virtual itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) @@ -376,9 +379,14 @@ signal.signal(signal.SIGPROF, self.sig_prof) signal.setitimer(self.itimer, 0.2, 0.2) - for i in range(100000000): + start_time = time.time() + while time.time() - start_time < 5.0: + # do some work + _ = pow(12345, 67890, 10000019) if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_prof handler stopped this itimer + else: + self.fail('timeout waiting for sig_prof signal') # profiling itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) Modified: sandbox/trunk/newgil/Lib/test/test_thread.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_thread.py (original) +++ sandbox/trunk/newgil/Lib/test/test_thread.py Sun Nov 1 12:17:37 2009 @@ -4,6 +4,7 @@ from test import support import _thread as thread import time +import weakref NUMTASKS = 10 @@ -99,6 +100,32 @@ thread.stack_size(0) + def test__count(self): + # Test the _count() function. + orig = thread._count() + mut = thread.allocate_lock() + mut.acquire() + started = [] + def task(): + started.append(None) + mut.acquire() + mut.release() + thread.start_new_thread(task, ()) + while not started: + time.sleep(0.01) + self.assertEquals(thread._count(), orig + 1) + # Allow the task to finish. + mut.release() + # The only reliable way to be sure that the thread ended from the + # interpreter's point of view is to wait for the function object to be + # destroyed. + done = [] + wr = weakref.ref(task, lambda _: done.append(None)) + del task + while not done: + time.sleep(0.01) + self.assertEquals(thread._count(), orig) + class Barrier: def __init__(self, num_threads): Modified: sandbox/trunk/newgil/Lib/test/test_xmlrpc.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_xmlrpc.py (original) +++ sandbox/trunk/newgil/Lib/test/test_xmlrpc.py Sun Nov 1 12:17:37 2009 @@ -798,6 +798,7 @@ len(content)) + at support.reap_threads def test_main(): xmlrpc_tests = [XMLRPCTestCase, HelperTestCase, DateTimeTestCase, BinaryTestCase, FaultTestCase] Modified: sandbox/trunk/newgil/Misc/NEWS ============================================================================== --- sandbox/trunk/newgil/Misc/NEWS (original) +++ sandbox/trunk/newgil/Misc/NEWS Sun Nov 1 12:17:37 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #3297: On wide unicode builds, do not split unicode characters into + surrogates. + - Remove length limitation when constructing a complex number from a string. - Issue #1087418: Boost performance of bitwise operations for longs. @@ -117,6 +120,14 @@ Library ------- +- Issue #7233: Fix a number of two-argument Decimal methods to make + sure that they accept an int or long as the second argument. Also + fix buggy handling of large arguments (those with coefficient longer + than the current precision) in shift and rotate. + +- Issue #4750: Store the basename of the original filename in the gzip FNAME + header as required by RFC 1952. + - Issue #1180: Added a new global option to ignore ~/.pydistutils.cfg in Distutils. @@ -301,6 +312,10 @@ Build ----- +- Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it + compiles correctly under gcc on x86-64. This fixes a reported + problem with the --with-tsc build on x86-64. + - Issue #6802: Fix build issues on MacOSX 10.6 - Issue #6244: Allow detect_tkinter to look for Tcl/Tk 8.6. @@ -323,6 +338,12 @@ Tests ----- +- Issue #7222: Make thread "reaping" more reliable so that reference + leak-chasing test runs give sensible results. The previous method of + reaping threads could return successfully while some Thread objects were + still referenced. This also introduces a new private function: + :func:`_thread._count()`. + - Issue #7151: fixed regrtest -j so that output to stderr from a test no longer runs the risk of causing the worker thread to fail. Modified: sandbox/trunk/newgil/Modules/_io/_iomodule.h ============================================================================== --- sandbox/trunk/newgil/Modules/_io/_iomodule.h (original) +++ sandbox/trunk/newgil/Modules/_io/_iomodule.h Sun Nov 1 12:17:37 2009 @@ -70,14 +70,6 @@ * Offset type for positioning. */ -/* Printing a variable of type off_t correctly and without producing - compiler warnings is surprisingly painful. We identify an integer - type whose size matches off_t and then: (1) cast the off_t to that - integer type and (2) use the appropriate conversion specification - for printf. The cast is necessary: gcc complains about formatting - a long with "%lld" even when both long and long long have the same - precision. */ - #if defined(MS_WIN64) || defined(MS_WINDOWS) /* Windows uses long long for offsets */ @@ -86,33 +78,26 @@ # define PyLong_FromOff_t PyLong_FromLongLong # define PY_OFF_T_MAX PY_LLONG_MAX # define PY_OFF_T_MIN PY_LLONG_MIN -# define PY_PRIdOFF "I64d" /* format to use in printf with type off_t */ -# define PY_OFF_T_COMPAT PY_LONG_LONG /* type compatible with off_t */ + #else /* Other platforms use off_t */ typedef off_t Py_off_t; -#if (HAVE_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG) +#if (SIZEOF_OFF_T == SIZEOF_SIZE_T) +# define PyLong_AsOff_t PyLong_AsSsize_t +# define PyLong_FromOff_t PyLong_FromSsize_t +# define PY_OFF_T_MAX PY_SSIZE_T_MAX +# define PY_OFF_T_MIN PY_SSIZE_T_MIN +#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) # define PyLong_AsOff_t PyLong_AsLongLong # define PyLong_FromOff_t PyLong_FromLongLong # define PY_OFF_T_MAX PY_LLONG_MAX # define PY_OFF_T_MIN PY_LLONG_MIN -# define PY_PRIdOFF "lld" -# define PY_OFF_T_COMPAT PY_LONG_LONG #elif (SIZEOF_OFF_T == SIZEOF_LONG) # define PyLong_AsOff_t PyLong_AsLong # define PyLong_FromOff_t PyLong_FromLong # define PY_OFF_T_MAX LONG_MAX # define PY_OFF_T_MIN LONG_MIN -# define PY_PRIdOFF "ld" -# define PY_OFF_T_COMPAT long -#elif (SIZEOF_OFF_T == SIZEOF_SIZE_T) -# define PyLong_AsOff_t PyLong_AsSsize_t -# define PyLong_FromOff_t PyLong_FromSsize_t -# define PY_OFF_T_MAX PY_SSIZE_T_MAX -# define PY_OFF_T_MIN PY_SSIZE_T_MIN -# define PY_PRIdOFF "zd" -# define PY_OFF_T_COMPAT Py_ssize_t #else # error off_t does not match either size_t, long, or long long! #endif Modified: sandbox/trunk/newgil/Modules/_io/bufferedio.c ============================================================================== --- sandbox/trunk/newgil/Modules/_io/bufferedio.c (original) +++ sandbox/trunk/newgil/Modules/_io/bufferedio.c Sun Nov 1 12:17:37 2009 @@ -580,8 +580,7 @@ if (n < 0) { if (!PyErr_Occurred()) PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %" PY_PRIdOFF, - (PY_OFF_T_COMPAT)n); + "Raw stream returned invalid position %zd", n); return -1; } self->abs_pos = n; @@ -613,8 +612,7 @@ if (n < 0) { if (!PyErr_Occurred()) PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %" PY_PRIdOFF, - (PY_OFF_T_COMPAT)n); + "Raw stream returned invalid position %zd", n); return -1; } self->abs_pos = n; Modified: sandbox/trunk/newgil/Modules/_threadmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/_threadmodule.c (original) +++ sandbox/trunk/newgil/Modules/_threadmodule.c Sun Nov 1 12:17:37 2009 @@ -14,7 +14,7 @@ #include "pythread.h" static PyObject *ThreadError; - +static long nb_threads = 0; /* Lock objects */ @@ -439,6 +439,7 @@ tstate = PyThreadState_New(boot->interp); PyEval_AcquireThread(tstate); + nb_threads++; res = PyEval_CallObjectWithKeywords( boot->func, boot->args, boot->keyw); if (res == NULL) { @@ -463,6 +464,7 @@ Py_DECREF(boot->args); Py_XDECREF(boot->keyw); PyMem_DEL(boot_raw); + nb_threads--; PyThreadState_Clear(tstate); PyThreadState_DeleteCurrent(); PyThread_exit_thread(); @@ -606,6 +608,24 @@ A thread's identity may be reused for another thread after it exits."); static PyObject * +thread__count(PyObject *self) +{ + return PyLong_FromLong(nb_threads); +} + +PyDoc_STRVAR(_count_doc, +"_count() -> integer\n\ +\n\ +\ +Return the number of currently running Python threads, excluding \n\ +the main thread. The returned number comprises all threads created\n\ +through `start_new_thread()` as well as `threading.Thread`, and not\n\ +yet finished.\n\ +\n\ +This function is meant for internal and specialized purposes only.\n\ +In most applications `threading.enumerate()` should be used instead."); + +static PyObject * thread_stack_size(PyObject *self, PyObject *args) { size_t old_size; @@ -678,6 +698,8 @@ METH_NOARGS, interrupt_doc}, {"get_ident", (PyCFunction)thread_get_ident, METH_NOARGS, get_ident_doc}, + {"_count", (PyCFunction)thread__count, + METH_NOARGS, _count_doc}, {"stack_size", (PyCFunction)thread_stack_size, METH_VARARGS, stack_size_doc}, @@ -748,6 +770,8 @@ if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) return NULL; + nb_threads = 0; + /* Initialize the C thread library */ PyThread_init_thread(); return m; Modified: sandbox/trunk/newgil/Python/ast.c ============================================================================== --- sandbox/trunk/newgil/Python/ast.c (original) +++ sandbox/trunk/newgil/Python/ast.c Sun Nov 1 12:17:37 2009 @@ -3246,10 +3246,11 @@ u = NULL; } else { /* check for integer overflow */ - if (len > PY_SIZE_MAX / 4) + if (len > PY_SIZE_MAX / 6) return NULL; - /* "\XX" may become "\u005c\uHHLL" (12 bytes) */ - u = PyBytes_FromStringAndSize((char *)NULL, len * 4); + /* "?" (2 bytes) may become "\U000000E4" (10 bytes), or 1:5 + "\?" (3 bytes) may become "\u005c\U000000E4" (16 bytes), or ~1:6 */ + u = PyBytes_FromStringAndSize((char *)NULL, len * 6); if (u == NULL) return NULL; p = buf = PyBytes_AsString(u); @@ -3266,20 +3267,24 @@ PyObject *w; char *r; Py_ssize_t rn, i; - w = decode_utf8(c, &s, end, "utf-16-be"); + w = decode_utf8(c, &s, end, "utf-32-be"); if (w == NULL) { Py_DECREF(u); return NULL; } r = PyBytes_AS_STRING(w); rn = Py_SIZE(w); - assert(rn % 2 == 0); - for (i = 0; i < rn; i += 2) { - sprintf(p, "\\u%02x%02x", + assert(rn % 4 == 0); + for (i = 0; i < rn; i += 4) { + sprintf(p, "\\U%02x%02x%02x%02x", r[i + 0] & 0xFF, - r[i + 1] & 0xFF); - p += 6; + r[i + 1] & 0xFF, + r[i + 2] & 0xFF, + r[i + 3] & 0xFF); + p += 10; } + /* Should be impossible to overflow */ + assert(p - buf <= Py_SIZE(u)); Py_DECREF(w); } else { *p++ = *s++; Modified: sandbox/trunk/newgil/Python/ceval.c ============================================================================== --- sandbox/trunk/newgil/Python/ceval.c (original) +++ sandbox/trunk/newgil/Python/ceval.c Sun Nov 1 12:17:37 2009 @@ -51,11 +51,29 @@ ((long*)(v))[1] = tb; } -#else /* this is for linux/x86 (and probably any other GCC/x86 combo) */ +#elif defined(__i386__) + +/* this is for linux/x86 (and probably any other GCC/x86 combo) */ #define READ_TIMESTAMP(val) \ __asm__ __volatile__("rdtsc" : "=A" (val)) +#elif defined(__x86_64__) + +/* for gcc/x86_64, the "A" constraint in DI mode means *either* rax *or* rdx; + not edx:eax as it does for i386. Since rdtsc puts its result in edx:eax + even in 64-bit mode, we need to use "a" and "d" for the lower and upper + 32-bit pieces of the result. */ + +#define READ_TIMESTAMP(val) \ + __asm__ __volatile__("rdtsc" : \ + "=a" (((int*)&(val))[0]), "=d" (((int*)&(val))[1])); + + +#else + +#error "Don't know how to implement timestamp counter for this architecture" + #endif void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1, From python-checkins at python.org Sun Nov 1 12:30:03 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 11:30:03 -0000 Subject: [Python-checkins] r76006 - sandbox/trunk/newgil/Python/ceval_gil.h Message-ID: Author: antoine.pitrou Date: Sun Nov 1 12:30:03 2009 New Revision: 76006 Log: Add a #define for priority requests, and disable them by default Modified: sandbox/trunk/newgil/Python/ceval_gil.h Modified: sandbox/trunk/newgil/Python/ceval_gil.h ============================================================================== --- sandbox/trunk/newgil/Python/ceval_gil.h (original) +++ sandbox/trunk/newgil/Python/ceval_gil.h Sun Nov 1 12:30:03 2009 @@ -17,6 +17,10 @@ #undef FORCE_SWITCHING #define FORCE_SWITCHING +/* Enable priority requests */ +#undef PRIO_REQUESTS +/* #define PRIO_REQUESTS */ + #undef TRACE_PRIO /* #define TRACE_PRIO */ @@ -171,12 +175,6 @@ In addition, the mutex also protects the above variables. */ static COND_T gil_cond; static MUTEX_T gil_mutex; -/* This mutex is taken when a priority request is made, and released when - it is finally honoured. - Other threads can sleep by trying to lock the mutex. */ -static MUTEX_T prio_mutex; -/* The thread making the prio request, or NULL. */ -static volatile PyThreadState *prio_request = NULL; #ifdef FORCE_SWITCHING /* This condition variable forces the GIL-releasing thread to wait for @@ -185,6 +183,12 @@ static MUTEX_T switch_mutex; #endif +/* This mutex is taken when a priority request is made, and released when + it is finally honoured. + Other threads can sleep by trying to lock the mutex. */ +static MUTEX_T prio_mutex; +/* The thread making the prio request, or NULL. */ +static volatile PyThreadState *prio_request = NULL; #define YIELD_IF_PRIO_REQUEST() \ do { \ @@ -195,7 +199,6 @@ } while (0) - static int gil_created(void) { return gil_locked >= 0; @@ -204,7 +207,9 @@ static void create_gil(void) { MUTEX_INIT(gil_mutex); +#ifdef PRIO_REQUESTS MUTEX_INIT(prio_mutex); +#endif #ifdef FORCE_SWITCHING MUTEX_INIT(switch_mutex); #endif @@ -258,7 +263,9 @@ /* If another thread is requesting priority, give it a chance to run before we take the mutex. */ +#ifdef PRIO_REQUESTS YIELD_IF_PRIO_REQUEST(); +#endif err = errno; MUTEX_LOCK(gil_mutex); @@ -356,7 +363,11 @@ static void take_gil_prio(PyThreadState *tstate) { +#ifdef PRIO_REQUESTS _take_gil(tstate, 1); +#else + _take_gil(tstate, 0); +#endif } void _PyEval_SetSwitchInterval(double seconds) From python-checkins at python.org Sun Nov 1 12:58:22 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 11:58:22 -0000 Subject: [Python-checkins] r76007 - python/trunk/Modules/_io/bufferedio.c Message-ID: Author: antoine.pitrou Date: Sun Nov 1 12:58:22 2009 New Revision: 76007 Log: Buffered I/O: optimize lock taking in the common non-contended case. Modified: python/trunk/Modules/_io/bufferedio.c Modified: python/trunk/Modules/_io/bufferedio.c ============================================================================== --- python/trunk/Modules/_io/bufferedio.c (original) +++ python/trunk/Modules/_io/bufferedio.c Sun Nov 1 12:58:22 2009 @@ -260,9 +260,11 @@ #ifdef WITH_THREAD #define ENTER_BUFFERED(self) \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS + if (!PyThread_acquire_lock(self->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock(self->lock, 1); \ + Py_END_ALLOW_THREADS \ + } #define LEAVE_BUFFERED(self) \ PyThread_release_lock(self->lock); From python-checkins at python.org Sun Nov 1 13:05:48 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 12:05:48 -0000 Subject: [Python-checkins] r76008 - in python/branches/py3k: Modules/_io/bufferedio.c Message-ID: Author: antoine.pitrou Date: Sun Nov 1 13:05:48 2009 New Revision: 76008 Log: Merged revisions 76007 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76007 | antoine.pitrou | 2009-11-01 12:58:22 +0100 (dim., 01 nov. 2009) | 3 lines Buffered I/O: optimize lock taking in the common non-contended case. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_io/bufferedio.c Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Sun Nov 1 13:05:48 2009 @@ -260,9 +260,11 @@ #ifdef WITH_THREAD #define ENTER_BUFFERED(self) \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS + if (!PyThread_acquire_lock(self->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock(self->lock, 1); \ + Py_END_ALLOW_THREADS \ + } #define LEAVE_BUFFERED(self) \ PyThread_release_lock(self->lock); From python-checkins at python.org Sun Nov 1 13:26:15 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 12:26:15 -0000 Subject: [Python-checkins] r76009 - in sandbox/trunk/newgil: Modules/_io/bufferedio.c Message-ID: Author: antoine.pitrou Date: Sun Nov 1 13:26:15 2009 New Revision: 76009 Log: Merged revisions 76008 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76008 | antoine.pitrou | 2009-11-01 13:05:48 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76007 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76007 | antoine.pitrou | 2009-11-01 12:58:22 +0100 (dim., 01 nov. 2009) | 3 lines Buffered I/O: optimize lock taking in the common non-contended case. ........ ................ Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Modules/_io/bufferedio.c Modified: sandbox/trunk/newgil/Modules/_io/bufferedio.c ============================================================================== --- sandbox/trunk/newgil/Modules/_io/bufferedio.c (original) +++ sandbox/trunk/newgil/Modules/_io/bufferedio.c Sun Nov 1 13:26:15 2009 @@ -260,9 +260,11 @@ #ifdef WITH_THREAD #define ENTER_BUFFERED(self) \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS + if (!PyThread_acquire_lock(self->lock, 0)) { \ + Py_BEGIN_ALLOW_THREADS \ + PyThread_acquire_lock(self->lock, 1); \ + Py_END_ALLOW_THREADS \ + } #define LEAVE_BUFFERED(self) \ PyThread_release_lock(self->lock); From python-checkins at python.org Sun Nov 1 16:59:12 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 15:59:12 -0000 Subject: [Python-checkins] r76010 - in python/branches/py3k/Lib/test: test_bytes.py test_multibytecodec_support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 16:59:11 2009 New Revision: 76010 Log: Fix test skipping in multibyte codec tests Modified: python/branches/py3k/Lib/test/test_bytes.py python/branches/py3k/Lib/test/test_multibytecodec_support.py Modified: python/branches/py3k/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k/Lib/test/test_bytes.py (original) +++ python/branches/py3k/Lib/test/test_bytes.py Sun Nov 1 16:59:11 2009 @@ -935,7 +935,7 @@ self.assertRaises(BytesWarning, operator.eq, bytearray(b''), '') self.assertRaises(BytesWarning, operator.ne, bytearray(b''), '') else: - # raise test.support.TestSkipped("BytesWarning is needed for this test: use -bb option") + # self.skipTest("BytesWarning is needed for this test: use -bb option") pass # Optimizations: Modified: python/branches/py3k/Lib/test/test_multibytecodec_support.py ============================================================================== --- python/branches/py3k/Lib/test/test_multibytecodec_support.py (original) +++ python/branches/py3k/Lib/test/test_multibytecodec_support.py Sun Nov 1 16:59:11 2009 @@ -279,7 +279,7 @@ try: self.open_mapping_file() # test it to report the error early except IOError: - raise support.TestSkipped("Could not retrieve "+self.mapfileurl) + self.skipTest("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): return support.open_urlresource(self.mapfileurl) From python-checkins at python.org Sun Nov 1 17:04:09 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 16:04:09 -0000 Subject: [Python-checkins] r76011 - in python/branches/release31-maint: Lib/test/test_bytes.py Lib/test/test_multibytecodec_support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 17:04:09 2009 New Revision: 76011 Log: Merged revisions 76010 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76010 | antoine.pitrou | 2009-11-01 16:59:11 +0100 (dim., 01 nov. 2009) | 3 lines Fix test skipping in multibyte codec tests ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_bytes.py python/branches/release31-maint/Lib/test/test_multibytecodec_support.py Modified: python/branches/release31-maint/Lib/test/test_bytes.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_bytes.py (original) +++ python/branches/release31-maint/Lib/test/test_bytes.py Sun Nov 1 17:04:09 2009 @@ -933,7 +933,7 @@ self.assertRaises(BytesWarning, operator.eq, bytearray(b''), '') self.assertRaises(BytesWarning, operator.ne, bytearray(b''), '') else: - # raise test.support.TestSkipped("BytesWarning is needed for this test: use -bb option") + # self.skipTest("BytesWarning is needed for this test: use -bb option") pass # Optimizations: Modified: python/branches/release31-maint/Lib/test/test_multibytecodec_support.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_multibytecodec_support.py (original) +++ python/branches/release31-maint/Lib/test/test_multibytecodec_support.py Sun Nov 1 17:04:09 2009 @@ -279,7 +279,7 @@ try: self.open_mapping_file() # test it to report the error early except IOError: - raise support.TestSkipped("Could not retrieve "+self.mapfileurl) + self.skipTest("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): return support.open_urlresource(self.mapfileurl) From python-checkins at python.org Sun Nov 1 17:10:47 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 16:10:47 -0000 Subject: [Python-checkins] r76012 - python/trunk/Lib/test/test_multibytecodec_support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 17:10:47 2009 New Revision: 76012 Log: Hum, test skipping when the URL isn't reachable hadn't been applied to trunk. Modified: python/trunk/Lib/test/test_multibytecodec_support.py Modified: python/trunk/Lib/test/test_multibytecodec_support.py ============================================================================== --- python/trunk/Lib/test/test_multibytecodec_support.py (original) +++ python/trunk/Lib/test/test_multibytecodec_support.py Sun Nov 1 17:10:47 2009 @@ -266,7 +266,10 @@ def __init__(self, *args, **kw): unittest.TestCase.__init__(self, *args, **kw) - self.open_mapping_file() # test it to report the error early + try: + self.open_mapping_file() # test it to report the error early + except IOError: + self.skipTest("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): return test_support.open_urlresource(self.mapfileurl) From python-checkins at python.org Sun Nov 1 17:13:08 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 16:13:08 -0000 Subject: [Python-checkins] r76013 - python/branches/py3k Message-ID: Author: antoine.pitrou Date: Sun Nov 1 17:13:08 2009 New Revision: 76013 Log: Blocked revisions 76012 via svnmerge ........ r76012 | antoine.pitrou | 2009-11-01 17:10:47 +0100 (dim., 01 nov. 2009) | 3 lines Hum, test skipping when the URL isn't reachable hadn't been applied to trunk. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Nov 1 17:17:06 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 16:17:06 -0000 Subject: [Python-checkins] r76014 - in python/branches/release26-maint: Lib/test/test_multibytecodec_support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 17:17:06 2009 New Revision: 76014 Log: (neither to 2.6) Merged revisions 76012 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76012 | antoine.pitrou | 2009-11-01 17:10:47 +0100 (dim., 01 nov. 2009) | 3 lines Hum, test skipping when the URL isn't reachable hadn't been applied to trunk. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_multibytecodec_support.py Modified: python/branches/release26-maint/Lib/test/test_multibytecodec_support.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_multibytecodec_support.py (original) +++ python/branches/release26-maint/Lib/test/test_multibytecodec_support.py Sun Nov 1 17:17:06 2009 @@ -266,7 +266,10 @@ def __init__(self, *args, **kw): unittest.TestCase.__init__(self, *args, **kw) - self.open_mapping_file() # test it to report the error early + try: + self.open_mapping_file() # test it to report the error early + except IOError: + raise test_support.TestSkipped("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): return test_support.open_urlresource(self.mapfileurl) From python-checkins at python.org Sun Nov 1 19:31:13 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 18:31:13 -0000 Subject: [Python-checkins] r76015 - in python/branches/release26-maint: Lib/getpass.py Misc/NEWS Message-ID: Author: gregory.p.smith Date: Sun Nov 1 19:31:13 2009 New Revision: 76015 Log: Merged revisions 76000 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76000 | gregory.p.smith | 2009-10-31 14:26:08 -0700 (Sat, 31 Oct 2009) | 7 lines Fixes issue7208 - getpass would still allow the password to be echoed on Solaris due to not flushing the input buffer. This change also incorporates some additional getpass implementation suggestions for security based on an analysis of getpass.c linked to from the issue. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/getpass.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/getpass.py ============================================================================== --- python/branches/release26-maint/Lib/getpass.py (original) +++ python/branches/release26-maint/Lib/getpass.py Sun Nov 1 19:31:13 2009 @@ -62,12 +62,16 @@ try: old = termios.tcgetattr(fd) # a copy to save new = old[:] - new[3] &= ~termios.ECHO # 3 == 'lflags' + new[3] &= ~(termios.ECHO|termios.ISIG) # 3 == 'lflags' + tcsetattr_flags = termios.TCSAFLUSH + if hasattr(termios, 'TCSASOFT'): + tcsetattr_flags |= termios.TCSASOFT try: - termios.tcsetattr(fd, termios.TCSADRAIN, new) + termios.tcsetattr(fd, tcsetattr_flags, new) passwd = _raw_input(prompt, stream, input=input) finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old) + termios.tcsetattr(fd, tcsetattr_flags, old) + stream.flush() # issue7208 except termios.error, e: if passwd is not None: # _raw_input succeeded. The final tcsetattr failed. Reraise @@ -125,6 +129,7 @@ if prompt: stream.write(prompt) stream.flush() + # NOTE: The Python C API calls flockfile() (and unlock) during readline. line = input.readline() if not line: raise EOFError Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Nov 1 19:31:13 2009 @@ -24,6 +24,12 @@ Library ------- +- Issue #7246 & Issue #7208: getpass now properly flushes input before + reading from stdin so that existing input does not confuse it and + lead to incorrect entry or an IOError. It also properly flushes it + afterwards to avoid the terminal echoing the input afterwards on + OSes such as Solaris. + - Issue #7244: itertools.izip_longest() no longer ignores exceptions raised during the formation of an output tuple. From python-checkins at python.org Sun Nov 1 19:33:56 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 18:33:56 -0000 Subject: [Python-checkins] r76016 - python/trunk/Misc/NEWS Message-ID: Author: gregory.p.smith Date: Sun Nov 1 19:33:55 2009 New Revision: 76016 Log: news entry for r76000 Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 1 19:33:55 2009 @@ -423,6 +423,12 @@ Library ------- +- Issue #7246 & Issue #7208: getpass now properly flushes input before + reading from stdin so that existing input does not confuse it and + lead to incorrect entry or an IOError. It also properly flushes it + afterwards to avoid the terminal echoing the input afterwards on + OSes such as Solaris. + - Issue #7233: Fix a number of two-argument Decimal methods to make sure that they accept an int or long as the second argument. Also fix buggy handling of large arguments (those with coefficient longer From python-checkins at python.org Sun Nov 1 19:42:18 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 18:42:18 -0000 Subject: [Python-checkins] r76017 - in python/branches/py3k: Lib/getpass.py Misc/NEWS Message-ID: Author: gregory.p.smith Date: Sun Nov 1 19:42:17 2009 New Revision: 76017 Log: Merged revisions 76000,76016 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76000 | gregory.p.smith | 2009-10-31 14:26:08 -0700 (Sat, 31 Oct 2009) | 7 lines Fixes issue7208 - getpass would still allow the password to be echoed on Solaris due to not flushing the input buffer. This change also incorporates some additional getpass implementation suggestions for security based on an analysis of getpass.c linked to from the issue. ........ r76016 | gregory.p.smith | 2009-11-01 10:33:55 -0800 (Sun, 01 Nov 2009) | 2 lines news entry for r76000 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/getpass.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/getpass.py ============================================================================== --- python/branches/py3k/Lib/getpass.py (original) +++ python/branches/py3k/Lib/getpass.py Sun Nov 1 19:42:17 2009 @@ -62,12 +62,16 @@ try: old = termios.tcgetattr(fd) # a copy to save new = old[:] - new[3] &= ~termios.ECHO # 3 == 'lflags' + new[3] &= ~(termios.ECHO|termios.ISIG) # 3 == 'lflags' + tcsetattr_flags = termios.TCSAFLUSH + if hasattr(termios, 'TCSASOFT'): + tcsetattr_flags |= termios.TCSASOFT try: - termios.tcsetattr(fd, termios.TCSADRAIN, new) + termios.tcsetattr(fd, tcsetattr_flags, new) passwd = _raw_input(prompt, stream, input=input) finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old) + termios.tcsetattr(fd, tcsetattr_flags, old) + stream.flush() # issue7208 except termios.error as e: if passwd is not None: # _raw_input succeeded. The final tcsetattr failed. Reraise @@ -124,6 +128,7 @@ if prompt: stream.write(prompt) stream.flush() + # NOTE: The Python C API calls flockfile() (and unlock) during readline. line = input.readline() if not line: raise EOFError Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 1 19:42:17 2009 @@ -120,6 +120,12 @@ Library ------- +- Issue #7246 & Issue #7208: getpass now properly flushes input before + reading from stdin so that existing input does not confuse it and + lead to incorrect entry or an IOError. It also properly flushes it + afterwards to avoid the terminal echoing the input afterwards on + OSes such as Solaris. + - Issue #7233: Fix a number of two-argument Decimal methods to make sure that they accept an int or long as the second argument. Also fix buggy handling of large arguments (those with coefficient longer From python-checkins at python.org Sun Nov 1 19:43:32 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 01 Nov 2009 18:43:32 -0000 Subject: [Python-checkins] r76018 - in python/branches/release26-maint: Lib/test/test_itertools.py Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Sun Nov 1 19:43:31 2009 New Revision: 76018 Log: Issue 7244: Fix indentation in C code. Fix test to not sent output to stdout. Modified: python/branches/release26-maint/Lib/test/test_itertools.py python/branches/release26-maint/Modules/itertoolsmodule.c Modified: python/branches/release26-maint/Lib/test/test_itertools.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_itertools.py (original) +++ python/branches/release26-maint/Lib/test/test_itertools.py Sun Nov 1 19:43:31 2009 @@ -422,7 +422,8 @@ def run(r1, r2): result = [] for i, j in izip_longest(r1, r2, fillvalue=0): - print(i, j) + with test_support.captured_output('stdout'): + print (i, j) result.append((i, j)) return result self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) @@ -431,8 +432,11 @@ # and StopIteration would stop as expected r1 = Repeater(1, 3, RuntimeError) r2 = Repeater(2, 4, StopIteration) - mylist = lambda it: [v for v in it] - self.assertRaises(RuntimeError, mylist, izip_longest(r1, r2, fillvalue=0)) + it = izip_longest(r1, r2, fillvalue=0) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertRaises(RuntimeError, next, it) def test_product(self): for args, result in [ @@ -723,7 +727,6 @@ self.assertRaises(StopIteration, f(lambda x:x, []).next) self.assertRaises(StopIteration, f(lambda x:x, StopNow()).next) - class TestExamples(unittest.TestCase): def test_chain(self): Modified: python/branches/release26-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release26-maint/Modules/itertoolsmodule.c Sun Nov 1 19:43:31 2009 @@ -3407,26 +3407,26 @@ Py_INCREF(result); for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); - if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + assert(PyIter_Check(it)); + item = PyIter_Next(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; + Py_DECREF(result); + return NULL; } else { - assert(PyIter_Check(it)); - item = PyIter_Next(it); - if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0 || PyErr_Occurred()) { - lz->numactive = 0; - Py_DECREF(result); - return NULL; - } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - PyTuple_SET_ITEM(lz->ittuple, i, NULL); - Py_DECREF(it); - } - } + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); } + } + } olditem = PyTuple_GET_ITEM(result, i); PyTuple_SET_ITEM(result, i, item); Py_DECREF(olditem); @@ -3437,26 +3437,26 @@ return NULL; for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); - if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - } else { - assert(PyIter_Check(it)); - item = PyIter_Next(it); - if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0 || PyErr_Occurred()) { - lz->numactive = 0; - Py_DECREF(result); - return NULL; - } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - PyTuple_SET_ITEM(lz->ittuple, i, NULL); - Py_DECREF(it); - } - } - } + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + assert(PyIter_Check(it)); + item = PyIter_Next(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } + } PyTuple_SET_ITEM(result, i, item); } } From python-checkins at python.org Sun Nov 1 19:48:31 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 18:48:31 -0000 Subject: [Python-checkins] r76019 - in python/branches/release31-maint: Lib/getpass.py Misc/NEWS Message-ID: Author: gregory.p.smith Date: Sun Nov 1 19:48:31 2009 New Revision: 76019 Log: Merged revisions 76017 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76017 | gregory.p.smith | 2009-11-01 10:42:17 -0800 (Sun, 01 Nov 2009) | 18 lines Merged revisions 76000,76016 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76000 | gregory.p.smith | 2009-10-31 14:26:08 -0700 (Sat, 31 Oct 2009) | 7 lines Fixes issue7208 - getpass would still allow the password to be echoed on Solaris due to not flushing the input buffer. This change also incorporates some additional getpass implementation suggestions for security based on an analysis of getpass.c linked to from the issue. ........ r76016 | gregory.p.smith | 2009-11-01 10:33:55 -0800 (Sun, 01 Nov 2009) | 2 lines news entry for r76000 ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/getpass.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/getpass.py ============================================================================== --- python/branches/release31-maint/Lib/getpass.py (original) +++ python/branches/release31-maint/Lib/getpass.py Sun Nov 1 19:48:31 2009 @@ -62,12 +62,16 @@ try: old = termios.tcgetattr(fd) # a copy to save new = old[:] - new[3] &= ~termios.ECHO # 3 == 'lflags' + new[3] &= ~(termios.ECHO|termios.ISIG) # 3 == 'lflags' + tcsetattr_flags = termios.TCSAFLUSH + if hasattr(termios, 'TCSASOFT'): + tcsetattr_flags |= termios.TCSASOFT try: - termios.tcsetattr(fd, termios.TCSADRAIN, new) + termios.tcsetattr(fd, tcsetattr_flags, new) passwd = _raw_input(prompt, stream, input=input) finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old) + termios.tcsetattr(fd, tcsetattr_flags, old) + stream.flush() # issue7208 except termios.error as e: if passwd is not None: # _raw_input succeeded. The final tcsetattr failed. Reraise @@ -124,6 +128,7 @@ if prompt: stream.write(prompt) stream.flush() + # NOTE: The Python C API calls flockfile() (and unlock) during readline. line = input.readline() if not line: raise EOFError Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Nov 1 19:48:31 2009 @@ -37,6 +37,12 @@ Library ------- +- Issue #7246 & Issue #7208: getpass now properly flushes input before + reading from stdin so that existing input does not confuse it and + lead to incorrect entry or an IOError. It also properly flushes it + afterwards to avoid the terminal echoing the input afterwards on + OSes such as Solaris. + - Issue #7233: Fix a number of two-argument Decimal methods to make sure that they accept an int or long as the second argument. Also fix buggy handling of large arguments (those with coefficient longer From python-checkins at python.org Sun Nov 1 20:24:18 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 19:24:18 -0000 Subject: [Python-checkins] r76020 - in python/branches/py3k: Modules/termios.c Message-ID: Author: gregory.p.smith Date: Sun Nov 1 20:24:18 2009 New Revision: 76020 Log: Merged revisions 75999 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75999 | gregory.p.smith | 2009-10-31 14:23:39 -0700 (Sat, 31 Oct 2009) | 2 lines Define TCSASOFT if the flag exists. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/termios.c Modified: python/branches/py3k/Modules/termios.c ============================================================================== --- python/branches/py3k/Modules/termios.c (original) +++ python/branches/py3k/Modules/termios.c Sun Nov 1 20:24:18 2009 @@ -355,6 +355,9 @@ {"TCSANOW", TCSANOW}, {"TCSADRAIN", TCSADRAIN}, {"TCSAFLUSH", TCSAFLUSH}, +#ifdef TCSASOFT + {"TCSASOFT", TCSASOFT}, +#endif /* tcflush() constants */ {"TCIFLUSH", TCIFLUSH}, From python-checkins at python.org Sun Nov 1 21:05:42 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 01 Nov 2009 20:05:42 -0000 Subject: [Python-checkins] r76021 - python/branches/release26-maint/Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Sun Nov 1 21:05:41 2009 New Revision: 76021 Log: Fix space/tabs issue. Modified: python/branches/release26-maint/Modules/itertoolsmodule.c Modified: python/branches/release26-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release26-maint/Modules/itertoolsmodule.c Sun Nov 1 21:05:41 2009 @@ -3392,75 +3392,75 @@ static PyObject * izip_longest_next(iziplongestobject *lz) { - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; - if (tuplesize == 0) - return NULL; + if (tuplesize == 0) + return NULL; if (lz->numactive == 0) return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - } else { - assert(PyIter_Check(it)); - item = PyIter_Next(it); - if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0 || PyErr_Occurred()) { - lz->numactive = 0; - Py_DECREF(result); - return NULL; + if (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - PyTuple_SET_ITEM(lz->ittuple, i, NULL); - Py_DECREF(it); + assert(PyIter_Check(it)); + item = PyIter_Next(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } } + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); } - } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); - if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - } else { - assert(PyIter_Check(it)); - item = PyIter_Next(it); - if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0 || PyErr_Occurred()) { - lz->numactive = 0; - Py_DECREF(result); + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) return NULL; - } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - PyTuple_SET_ITEM(lz->ittuple, i, NULL); - Py_DECREF(it); - } + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + assert(PyIter_Check(it)); + item = PyIter_Next(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } + } + PyTuple_SET_ITEM(result, i, item); } - } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; + } + return result; } PyDoc_STRVAR(izip_longest_doc, From python-checkins at python.org Sun Nov 1 21:28:48 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 20:28:48 -0000 Subject: [Python-checkins] r76022 - in python/branches/release26-maint: Lib/test/test_socket.py Misc/NEWS Modules/socketmodule.c Message-ID: Author: gregory.p.smith Date: Sun Nov 1 21:28:48 2009 New Revision: 76022 Log: Merged revisions 69519 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r69519 | gregory.p.smith | 2009-02-11 15:45:25 -0800 (Wed, 11 Feb 2009) | 3 lines Issue #1008086: Fixes socket.inet_aton() to always return 4 bytes even on LP64 platforms (most 64-bit Linux, bsd, unix systems). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_socket.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/socketmodule.c Modified: python/branches/release26-maint/Lib/test/test_socket.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_socket.py (original) +++ python/branches/release26-maint/Lib/test/test_socket.py Sun Nov 1 21:28:48 2009 @@ -385,6 +385,14 @@ # Check that setting it to an invalid type raises TypeError self.assertRaises(TypeError, socket.setdefaulttimeout, "spam") + def testIPv4_inet_aton_fourbytes(self): + if not hasattr(socket, 'inet_aton'): + return # No inet_aton, nothing to check + # Test that issue1008086 and issue767150 are fixed. + # It must return 4 bytes. + self.assertEquals('\x00'*4, socket.inet_aton('0.0.0.0')) + self.assertEquals('\xff'*4, socket.inet_aton('255.255.255.255')) + def testIPv4toString(self): if not hasattr(socket, 'inet_pton'): return # No inet_pton() on this platform Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Nov 1 21:28:48 2009 @@ -24,6 +24,9 @@ Library ------- +- Issue #1008086: Fixed socket.inet_aton() to always return 4 bytes even on + LP64 platforms (most 64-bit Linux, bsd, unix systems). + - Issue #7246 & Issue #7208: getpass now properly flushes input before reading from stdin so that existing input does not confuse it and lead to incorrect entry or an IOError. It also properly flushes it Modified: python/branches/release26-maint/Modules/socketmodule.c ============================================================================== --- python/branches/release26-maint/Modules/socketmodule.c (original) +++ python/branches/release26-maint/Modules/socketmodule.c Sun Nov 1 21:28:48 2009 @@ -3745,8 +3745,11 @@ #endif #if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK) +#if (SIZEOF_INT != 4) +#error "Not sure if in_addr_t exists and int is not 32-bits." +#endif /* Have to use inet_addr() instead */ - unsigned long packed_addr; + unsigned int packed_addr; #endif char *ip_addr; @@ -5284,7 +5287,10 @@ inet_pton(int af, const char *src, void *dst) { if (af == AF_INET) { - long packed_addr; +#if (SIZEOF_INT != 4) +#error "Not sure if in_addr_t exists and int is not 32-bits." +#endif + unsigned int packed_addr; packed_addr = inet_addr(src); if (packed_addr == INADDR_NONE) return 0; From python-checkins at python.org Sun Nov 1 21:33:32 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 20:33:32 -0000 Subject: [Python-checkins] r76023 - in python/branches/release26-maint: Lib/fnmatch.py Lib/test/test_fnmatch.py Misc/NEWS Message-ID: Author: gregory.p.smith Date: Sun Nov 1 21:33:31 2009 New Revision: 76023 Log: Merged revisions 74475 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r74475 | gregory.p.smith | 2009-08-16 11:52:58 -0700 (Sun, 16 Aug 2009) | 2 lines Issue 6665: Fix fnmatch to properly match filenames with newlines in them. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/fnmatch.py python/branches/release26-maint/Lib/test/test_fnmatch.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/fnmatch.py ============================================================================== --- python/branches/release26-maint/Lib/fnmatch.py (original) +++ python/branches/release26-maint/Lib/fnmatch.py Sun Nov 1 21:33:31 2009 @@ -104,4 +104,4 @@ res = '%s[%s]' % (res, stuff) else: res = res + re.escape(c) - return res + "$" + return res + '\Z(?ms)' Modified: python/branches/release26-maint/Lib/test/test_fnmatch.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_fnmatch.py (original) +++ python/branches/release26-maint/Lib/test/test_fnmatch.py Sun Nov 1 21:33:31 2009 @@ -32,11 +32,18 @@ check('a', 'b', 0) # these test that '\' is handled correctly in character sets; - # see SF bug #??? + # see SF bug #409651 check('\\', r'[\]') check('a', r'[!\]') check('\\', r'[!\]', 0) + # test that filenames with newlines in them are handled correctly. + # http://bugs.python.org/issue6665 + check('foo\nbar', 'foo*') + check('foo\nbar\n', 'foo*') + check('\nfoo', 'foo*', False) + check('\n', '*') + def test_main(): test_support.run_unittest(FnmatchTestCase) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Nov 1 21:33:31 2009 @@ -24,6 +24,8 @@ Library ------- +- Issue #6665: Fix fnmatch to properly match filenames with newlines in them. + - Issue #1008086: Fixed socket.inet_aton() to always return 4 bytes even on LP64 platforms (most 64-bit Linux, bsd, unix systems). From python-checkins at python.org Sun Nov 1 21:36:24 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 20:36:24 -0000 Subject: [Python-checkins] r76024 - in python/branches/release31-maint: Lib/fnmatch.py Lib/test/test_fnmatch.py Misc/NEWS Message-ID: Author: gregory.p.smith Date: Sun Nov 1 21:36:24 2009 New Revision: 76024 Log: Merged revisions 74476 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r74476 | gregory.p.smith | 2009-08-16 11:58:46 -0700 (Sun, 16 Aug 2009) | 9 lines Merged revisions 74475 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r74475 | gregory.p.smith | 2009-08-16 11:52:58 -0700 (Sun, 16 Aug 2009) | 2 lines Issue 6665: Fix fnmatch to properly match filenames with newlines in them. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/fnmatch.py python/branches/release31-maint/Lib/test/test_fnmatch.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/fnmatch.py ============================================================================== --- python/branches/release31-maint/Lib/fnmatch.py (original) +++ python/branches/release31-maint/Lib/fnmatch.py Sun Nov 1 21:36:24 2009 @@ -113,4 +113,4 @@ res = '%s[%s]' % (res, stuff) else: res = res + re.escape(c) - return res + "$" + return res + '\Z(?ms)' Modified: python/branches/release31-maint/Lib/test/test_fnmatch.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_fnmatch.py (original) +++ python/branches/release31-maint/Lib/test/test_fnmatch.py Sun Nov 1 21:36:24 2009 @@ -32,11 +32,18 @@ check('a', 'b', 0) # these test that '\' is handled correctly in character sets; - # see SF bug #??? + # see SF bug #409651 check('\\', r'[\]') check('a', r'[!\]') check('\\', r'[!\]', 0) + # test that filenames with newlines in them are handled correctly. + # http://bugs.python.org/issue6665 + check('foo\nbar', 'foo*') + check('foo\nbar\n', 'foo*') + check('\nfoo', 'foo*', False) + check('\n', '*') + def test_mix_bytes_str(self): self.assertRaises(TypeError, fnmatch, 'test', b'*') self.assertRaises(TypeError, fnmatch, b'test', '*') @@ -46,6 +53,8 @@ def test_bytes(self): self.check_match(b'test', b'te*') self.check_match(b'test\xff', b'te*\xff') + self.check_match(b'foo\nbar', b'foo*') + def test_main(): support.run_unittest(FnmatchTestCase) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Nov 1 21:36:24 2009 @@ -37,6 +37,8 @@ Library ------- +- Issue #6665: Fix fnmatch to properly match filenames with newlines in them. + - Issue #7246 & Issue #7208: getpass now properly flushes input before reading from stdin so that existing input does not confuse it and lead to incorrect entry or an IOError. It also properly flushes it From python-checkins at python.org Sun Nov 1 21:45:17 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 01 Nov 2009 20:45:17 -0000 Subject: [Python-checkins] r76025 - in python/trunk: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Sun Nov 1 21:45:16 2009 New Revision: 76025 Log: Fix exception handling in itertools.izip_longest(). Modified: python/trunk/Lib/test/test_itertools.py python/trunk/Misc/NEWS python/trunk/Modules/itertoolsmodule.c Modified: python/trunk/Lib/test/test_itertools.py ============================================================================== --- python/trunk/Lib/test/test_itertools.py (original) +++ python/trunk/Lib/test/test_itertools.py Sun Nov 1 21:45:16 2009 @@ -571,6 +571,46 @@ ids = map(id, list(izip_longest('abc', 'def'))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_bug_7244(self): + + class Repeater(object): + # this class is similar to itertools.repeat + def __init__(self, o, t, e): + self.o = o + self.t = int(t) + self.e = e + def __iter__(self): # its iterator is itself + return self + def next(self): + if self.t > 0: + self.t -= 1 + return self.o + else: + raise self.e + + # Formerly this code in would fail in debug mode + # with Undetected Error and Stop Iteration + r1 = Repeater(1, 3, StopIteration) + r2 = Repeater(2, 4, StopIteration) + def run(r1, r2): + result = [] + for i, j in izip_longest(r1, r2, fillvalue=0): + with test_support.captured_output('stdout'): + print (i, j) + result.append((i, j)) + return result + self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) + + # Formerly, the RuntimeError would be lost + # and StopIteration would stop as expected + r1 = Repeater(1, 3, RuntimeError) + r2 = Repeater(2, 4, StopIteration) + it = izip_longest(r1, r2, fillvalue=0) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertRaises(RuntimeError, next, it) + def test_product(self): for args, result in [ ([], [()]), # zero iterables Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 1 21:45:16 2009 @@ -15,6 +15,9 @@ - Remove length limitation when constructing a complex number from a unicode string. +- Issue #7244: itertools.izip_longest() no longer ignores exceptions + raised during the formation of an output tuple. + - Issue #1087418: Boost performance of bitwise operations for longs. - Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Sun Nov 1 21:45:16 2009 @@ -3865,71 +3865,73 @@ static PyObject * izip_longest_next(iziplongestobject *lz) { - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; - if (tuplesize == 0) - return NULL; + if (tuplesize == 0) + return NULL; if (lz->numactive == 0) return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + if (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); + } + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) + return NULL; + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; + PyTuple_SET_ITEM(result, i, item); + } + } + return result; } PyDoc_STRVAR(izip_longest_doc, From python-checkins at python.org Sun Nov 1 21:55:33 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 01 Nov 2009 20:55:33 -0000 Subject: [Python-checkins] r76026 - in python/branches/py3k: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Sun Nov 1 21:55:33 2009 New Revision: 76026 Log: Fix exception handling in itertools.izip_longest(). Modified: python/branches/py3k/Lib/test/test_itertools.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/itertoolsmodule.c Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Sun Nov 1 21:55:33 2009 @@ -581,6 +581,46 @@ ids = list(map(id, list(zip_longest('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_bug_7244(self): + + class Repeater: + # this class is similar to itertools.repeat + def __init__(self, o, t, e): + self.o = o + self.t = int(t) + self.e = e + def __iter__(self): # its iterator is itself + return self + def __next__(self): + if self.t > 0: + self.t -= 1 + return self.o + else: + raise self.e + + # Formerly this code in would fail in debug mode + # with Undetected Error and Stop Iteration + r1 = Repeater(1, 3, StopIteration) + r2 = Repeater(2, 4, StopIteration) + def run(r1, r2): + result = [] + for i, j in zip_longest(r1, r2, fillvalue=0): + with support.captured_output('stdout'): + print((i, j)) + result.append((i, j)) + return result + self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) + + # Formerly, the RuntimeError would be lost + # and StopIteration would stop as expected + r1 = Repeater(1, 3, RuntimeError) + r2 = Repeater(2, 4, StopIteration) + it = zip_longest(r1, r2, fillvalue=0) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertRaises(RuntimeError, next, it) + def test_product(self): for args, result in [ ([], [()]), # zero iterables Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 1 21:55:33 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7244: itertools.izip_longest() no longer ignores exceptions + raised during the formation of an output tuple. + - Issue #3297: On wide unicode builds, do not split unicode characters into surrogates. Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Sun Nov 1 21:55:33 2009 @@ -3344,71 +3344,73 @@ static PyObject * zip_longest_next(ziplongestobject *lz) { - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; - if (tuplesize == 0) - return NULL; + if (tuplesize == 0) + return NULL; if (lz->numactive == 0) return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + if (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); + } + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) + return NULL; + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; + PyTuple_SET_ITEM(result, i, item); + } + } + return result; } PyDoc_STRVAR(zip_longest_doc, From python-checkins at python.org Sun Nov 1 22:02:39 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 01 Nov 2009 21:02:39 -0000 Subject: [Python-checkins] r76027 - in python/branches/release31-maint: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Sun Nov 1 22:02:38 2009 New Revision: 76027 Log: Fix exception handling in itertools.izip_longest(). Modified: python/branches/release31-maint/Lib/test/test_itertools.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/itertoolsmodule.c Modified: python/branches/release31-maint/Lib/test/test_itertools.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_itertools.py (original) +++ python/branches/release31-maint/Lib/test/test_itertools.py Sun Nov 1 22:02:38 2009 @@ -581,6 +581,46 @@ ids = list(map(id, list(zip_longest('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_bug_7244(self): + + class Repeater: + # this class is similar to itertools.repeat + def __init__(self, o, t, e): + self.o = o + self.t = int(t) + self.e = e + def __iter__(self): # its iterator is itself + return self + def __next__(self): + if self.t > 0: + self.t -= 1 + return self.o + else: + raise self.e + + # Formerly this code in would fail in debug mode + # with Undetected Error and Stop Iteration + r1 = Repeater(1, 3, StopIteration) + r2 = Repeater(2, 4, StopIteration) + def run(r1, r2): + result = [] + for i, j in zip_longest(r1, r2, fillvalue=0): + with support.captured_output('stdout'): + print((i, j)) + result.append((i, j)) + return result + self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) + + # Formerly, the RuntimeError would be lost + # and StopIteration would stop as expected + r1 = Repeater(1, 3, RuntimeError) + r2 = Repeater(2, 4, StopIteration) + it = zip_longest(r1, r2, fillvalue=0) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertRaises(RuntimeError, next, it) + def test_product(self): for args, result in [ ([], [()]), # zero iterables Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Nov 1 22:02:38 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7244: itertools.izip_longest() no longer ignores exceptions + raised during the formation of an output tuple. + - Issue #3297: On wide unicode builds, do not split unicode characters into surrogates. Modified: python/branches/release31-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release31-maint/Modules/itertoolsmodule.c Sun Nov 1 22:02:38 2009 @@ -3344,71 +3344,73 @@ static PyObject * zip_longest_next(ziplongestobject *lz) { - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; - if (tuplesize == 0) - return NULL; + if (tuplesize == 0) + return NULL; if (lz->numactive == 0) return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + if (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); + } + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) + return NULL; + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; + PyTuple_SET_ITEM(result, i, item); + } + } + return result; } PyDoc_STRVAR(zip_longest_doc, From python-checkins at python.org Sun Nov 1 22:02:52 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 21:02:52 -0000 Subject: [Python-checkins] r76028 - python/trunk/configure.in Message-ID: Author: gregory.p.smith Date: Sun Nov 1 22:02:52 2009 New Revision: 76028 Log: issue1115: convert some AC_TRY_RUNs into AC_TRY_COMPILEs. Modified: python/trunk/configure.in Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sun Nov 1 22:02:52 2009 @@ -918,9 +918,8 @@ ac_save_cc="$CC" CC="$CC -fno-strict-aliasing" AC_CACHE_VAL(ac_cv_no_strict_aliasing_ok, - AC_TRY_RUN([int main() { return 0; }], + AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_no_strict_aliasing_ok=yes, - ac_cv_no_strict_aliasing_ok=no, ac_cv_no_strict_aliasing_ok=no)) CC="$ac_save_cc" AC_MSG_RESULT($ac_cv_no_strict_aliasing_ok) @@ -1067,10 +1066,10 @@ AC_CACHE_VAL(ac_cv_opt_olimit_ok, [ac_save_cc="$CC" CC="$CC -OPT:Olimit=0" -AC_TRY_RUN([int main() { return 0; }], +AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_opt_olimit_ok=yes, ac_cv_opt_olimit_ok=no, - ac_cv_opt_olimit_ok=no) + ) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_opt_olimit_ok) if test $ac_cv_opt_olimit_ok = yes; then @@ -1089,10 +1088,10 @@ AC_CACHE_VAL(ac_cv_olimit_ok, [ac_save_cc="$CC" CC="$CC -Olimit 1500" - AC_TRY_RUN([int main() { return 0; }], + AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_olimit_ok=yes, ac_cv_olimit_ok=no, - ac_cv_olimit_ok=no) + ) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_olimit_ok) if test $ac_cv_olimit_ok = yes; then From python-checkins at python.org Sun Nov 1 22:03:39 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 21:03:39 -0000 Subject: [Python-checkins] r76029 - python/trunk/configure Message-ID: Author: gregory.p.smith Date: Sun Nov 1 22:03:38 2009 New Revision: 76029 Log: configure generated from r76028 Modified: python/trunk/configure Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sun Nov 1 22:03:38 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 75664 . +# From configure.in Revision: 76028 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -4621,50 +4621,47 @@ if test "${ac_cv_no_strict_aliasing_ok+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test "$cross_compiling" = yes; then - ac_cv_no_strict_aliasing_ok=no -else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_no_strict_aliasing_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_no_strict_aliasing_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_no_strict_aliasing_ok=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi CC="$ac_save_cc" @@ -4818,50 +4815,47 @@ else ac_save_cc="$CC" CC="$CC -OPT:Olimit=0" -if test "$cross_compiling" = yes; then - ac_cv_opt_olimit_ok=no -else - cat >conftest.$ac_ext <<_ACEOF +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_opt_olimit_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_opt_olimit_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_opt_olimit_ok=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CC="$ac_save_cc" fi @@ -4886,50 +4880,47 @@ else ac_save_cc="$CC" CC="$CC -Olimit 1500" - if test "$cross_compiling" = yes; then - ac_cv_olimit_ok=no -else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_olimit_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_olimit_ok=no + ac_cv_olimit_ok=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CC="$ac_save_cc" fi From python-checkins at python.org Sun Nov 1 22:09:10 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 21:09:10 -0000 Subject: [Python-checkins] r76030 - in python/branches/py3k: configure.in Message-ID: Author: gregory.p.smith Date: Sun Nov 1 22:09:10 2009 New Revision: 76030 Log: Merged revisions 76028 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76028 | gregory.p.smith | 2009-11-01 13:02:52 -0800 (Sun, 01 Nov 2009) | 2 lines issue1115: convert some AC_TRY_RUNs into AC_TRY_COMPILEs. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/configure.in Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Nov 1 22:09:10 2009 @@ -856,9 +856,8 @@ ac_save_cc="$CC" CC="$CC -fno-strict-aliasing" AC_CACHE_VAL(ac_cv_no_strict_aliasing_ok, - AC_TRY_RUN([int main() { return 0; }], + AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_no_strict_aliasing_ok=yes, - ac_cv_no_strict_aliasing_ok=no, ac_cv_no_strict_aliasing_ok=no)) CC="$ac_save_cc" AC_MSG_RESULT($ac_cv_no_strict_aliasing_ok) @@ -1005,10 +1004,10 @@ AC_CACHE_VAL(ac_cv_opt_olimit_ok, [ac_save_cc="$CC" CC="$CC -OPT:Olimit=0" -AC_TRY_RUN([int main() { return 0; }], +AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_opt_olimit_ok=yes, ac_cv_opt_olimit_ok=no, - ac_cv_opt_olimit_ok=no) + ) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_opt_olimit_ok) if test $ac_cv_opt_olimit_ok = yes; then @@ -1027,10 +1026,10 @@ AC_CACHE_VAL(ac_cv_olimit_ok, [ac_save_cc="$CC" CC="$CC -Olimit 1500" - AC_TRY_RUN([int main() { return 0; }], + AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_olimit_ok=yes, ac_cv_olimit_ok=no, - ac_cv_olimit_ok=no) + ) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_olimit_ok) if test $ac_cv_olimit_ok = yes; then From python-checkins at python.org Sun Nov 1 22:10:57 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 21:10:57 -0000 Subject: [Python-checkins] r76031 - python/branches/py3k Message-ID: Author: gregory.p.smith Date: Sun Nov 1 22:10:57 2009 New Revision: 76031 Log: block r76029 Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Nov 1 22:11:36 2009 From: python-checkins at python.org (gregory.p.smith) Date: Sun, 01 Nov 2009 21:11:36 -0000 Subject: [Python-checkins] r76032 - python/branches/py3k/configure Message-ID: Author: gregory.p.smith Date: Sun Nov 1 22:11:36 2009 New Revision: 76032 Log: generated from r76030 Modified: python/branches/py3k/configure Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Nov 1 22:11:36 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 75684 . +# From configure.in Revision: 76030 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -4546,50 +4546,47 @@ if test "${ac_cv_no_strict_aliasing_ok+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test "$cross_compiling" = yes; then - ac_cv_no_strict_aliasing_ok=no -else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_no_strict_aliasing_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_no_strict_aliasing_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_no_strict_aliasing_ok=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi CC="$ac_save_cc" @@ -4743,50 +4740,47 @@ else ac_save_cc="$CC" CC="$CC -OPT:Olimit=0" -if test "$cross_compiling" = yes; then - ac_cv_opt_olimit_ok=no -else - cat >conftest.$ac_ext <<_ACEOF +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_opt_olimit_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_opt_olimit_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_opt_olimit_ok=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CC="$ac_save_cc" fi @@ -4811,50 +4805,47 @@ else ac_save_cc="$CC" CC="$CC -Olimit 1500" - if test "$cross_compiling" = yes; then - ac_cv_olimit_ok=no -else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_olimit_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_olimit_ok=no + ac_cv_olimit_ok=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CC="$ac_save_cc" fi From python-checkins at python.org Sun Nov 1 22:26:14 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 21:26:14 -0000 Subject: [Python-checkins] r76033 - python/trunk/Lib/test/test_normalization.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 22:26:14 2009 New Revision: 76033 Log: test_normalization should skip and not crash when the resource isn't available Modified: python/trunk/Lib/test/test_normalization.py Modified: python/trunk/Lib/test/test_normalization.py ============================================================================== --- python/trunk/Lib/test/test_normalization.py (original) +++ python/trunk/Lib/test/test_normalization.py Sun Nov 1 22:26:14 2009 @@ -40,6 +40,11 @@ class NormalizationTest(unittest.TestCase): def test_main(self): part1_data = {} + # Hit the exception early + try: + open_urlresource(TESTDATAURL) + except IOError: + self.skipTest("Could not retrieve " + TESTDATAURL) for line in open_urlresource(TESTDATAURL): if '#' in line: line = line.split('#')[0] @@ -95,8 +100,6 @@ def test_main(): - # Hit the exception early - open_urlresource(TESTDATAURL) run_unittest(NormalizationTest) if __name__ == "__main__": From python-checkins at python.org Sun Nov 1 22:29:34 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 21:29:34 -0000 Subject: [Python-checkins] r76034 - in python/trunk/Lib: mailbox.py test/test_mailbox.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 22:29:33 2009 New Revision: 76034 Log: This should finally fix #6896. Let's watch the buildbots. Modified: python/trunk/Lib/mailbox.py python/trunk/Lib/test/test_mailbox.py Modified: python/trunk/Lib/mailbox.py ============================================================================== --- python/trunk/Lib/mailbox.py (original) +++ python/trunk/Lib/mailbox.py Sun Nov 1 22:29:33 2009 @@ -238,6 +238,9 @@ raise NoSuchMailboxError(self._path) self._toc = {} self._last_read = None # Records last time we read cur/new + # NOTE: we manually invalidate _last_read each time we do any + # modifications ourselves, otherwise we might get tripped up by + # bogus mtime behaviour on some systems (see issue #6896). def add(self, message): """Add message and return assigned key.""" @@ -271,11 +274,15 @@ raise if isinstance(message, MaildirMessage): os.utime(dest, (os.path.getatime(dest), message.get_date())) + # Invalidate cached toc + self._last_read = None return uniq def remove(self, key): """Remove the keyed message; raise KeyError if it doesn't exist.""" os.remove(os.path.join(self._path, self._lookup(key))) + # Invalidate cached toc (only on success) + self._last_read = None def discard(self, key): """If the keyed message exists, remove it.""" @@ -310,6 +317,8 @@ if isinstance(message, MaildirMessage): os.utime(new_path, (os.path.getatime(new_path), message.get_date())) + # Invalidate cached toc + self._last_read = None def get_message(self, key): """Return a Message representation or raise a KeyError.""" @@ -364,7 +373,9 @@ def flush(self): """Write any pending changes to disk.""" - return # Maildir changes are always written immediately. + # Maildir changes are always written immediately, so there's nothing + # to do except invalidate our cached toc. + self._last_read = None def lock(self): """Lock the mailbox.""" Modified: python/trunk/Lib/test/test_mailbox.py ============================================================================== --- python/trunk/Lib/test/test_mailbox.py (original) +++ python/trunk/Lib/test/test_mailbox.py Sun Nov 1 22:29:33 2009 @@ -684,6 +684,9 @@ self.assertEqual(self._box._lookup(key0), os.path.join('new', key0)) os.remove(os.path.join(self._path, 'new', key0)) self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)}) + # Be sure that the TOC is read back from disk (see issue #6896 + # about bad mtime behaviour on some systems). + self._box.flush() self.assertRaises(KeyError, lambda: self._box._lookup(key0)) self.assertEqual(self._box._toc, {}) From nnorwitz at gmail.com Sun Nov 1 22:32:11 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 1 Nov 2009 16:32:11 -0500 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20091101213211.GA8222@kbk-i386-bb.psfb.org> 334 tests OK. 1 test failed: test_normalization 1 test altered the execution environment: test_distutils 40 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 10 skips unexpected on linux2: test_multiprocessing test_codecmaps_tw test_codecmaps_cn test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_codecmaps_jp test_codecmaps_kr test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ... fetching http://people.freebsd.org/~perky/i18n/EUC-CN.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT ... test_codecmaps_cn skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT test_codecmaps_hk fetching http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT ... test_codecmaps_jp fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ... test_codecmaps_jp skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT test_codecmaps_kr fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ... test_codecmaps_kr skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT test_codecmaps_tw fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ... test_codecmaps_tw skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19564 refs] Warning -- sys.stdout was modified by test_distutils test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15425 refs] [15425 refs] [15425 refs] [25439 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization fetching http://www.unicode.org/Public/5.1.0/ucd/NormalizationTest.txt ... test test_normalization crashed -- : [Errno socket error] [Errno 110] Connection timed out test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17013 refs] [17013 refs] test_plistlib test_poll test_popen [15430 refs] [15430 refs] [15430 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20924 refs] [20924 refs] [20924 refs] [20924 refs] [20924 refs] [20923 refs] [20923 refs] test_pyexpat test_queue test_quopri [17951 refs] [17951 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15425 refs] [15425 refs] [15428 refs] [15425 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [17286 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] . [15425 refs] [15425 refs] this bit of output is from a test of stdout in a different process ... [15425 refs] [15425 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [17286 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] . [15425 refs] [15425 refs] this bit of output is from a test of stdout in a different process ... [15425 refs] [15425 refs] [15640 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15425 refs] [15425 refs] [15654 refs] [15448 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:654: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1978: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15428 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18738 refs] [20298 refs] [20112 refs] [20112 refs] [20112 refs] [20112 refs] test_threading_local test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 334 tests OK. 1 test failed: test_normalization 1 test altered the execution environment: test_distutils 40 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 10 skips unexpected on linux2: test_multiprocessing test_codecmaps_tw test_codecmaps_cn test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_codecmaps_jp test_codecmaps_kr [881513 refs] From python-checkins at python.org Sun Nov 1 22:34:42 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 21:34:42 -0000 Subject: [Python-checkins] r76035 - in python/branches/release26-maint: Lib/test/test_normalization.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 22:34:42 2009 New Revision: 76035 Log: Merged revisions 76033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76033 | antoine.pitrou | 2009-11-01 22:26:14 +0100 (dim., 01 nov. 2009) | 3 lines test_normalization should skip and not crash when the resource isn't available ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_normalization.py Modified: python/branches/release26-maint/Lib/test/test_normalization.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_normalization.py (original) +++ python/branches/release26-maint/Lib/test/test_normalization.py Sun Nov 1 22:34:42 2009 @@ -1,4 +1,4 @@ -from test.test_support import run_unittest, open_urlresource +from test.test_support import run_unittest, open_urlresource, TestSkipped import unittest import sys @@ -96,7 +96,10 @@ def test_main(): # Hit the exception early - open_urlresource(TESTDATAURL) + try: + open_urlresource(TESTDATAURL) + except IOError: + raise TestSkipped("could not retrieve " + TESTDATAURL) run_unittest(NormalizationTest) if __name__ == "__main__": From python-checkins at python.org Sun Nov 1 22:43:21 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 21:43:21 -0000 Subject: [Python-checkins] r76036 - in python/branches/py3k: Lib/test/test_normalization.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 22:43:20 2009 New Revision: 76036 Log: Merged revisions 76033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76033 | antoine.pitrou | 2009-11-01 22:26:14 +0100 (dim., 01 nov. 2009) | 3 lines test_normalization should skip and not crash when the resource isn't available ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_normalization.py Modified: python/branches/py3k/Lib/test/test_normalization.py ============================================================================== --- python/branches/py3k/Lib/test/test_normalization.py (original) +++ python/branches/py3k/Lib/test/test_normalization.py Sun Nov 1 22:43:20 2009 @@ -42,6 +42,11 @@ class NormalizationTest(unittest.TestCase): def test_main(self): part1_data = {} + # Hit the exception early + try: + open_urlresource(TESTDATAURL, encoding="utf-8") + except IOError: + self.skipTest("Could not retrieve " + TESTDATAURL) for line in open_urlresource(TESTDATAURL, encoding="utf-8"): if '#' in line: line = line.split('#')[0] @@ -97,8 +102,6 @@ def test_main(): - # Skip the test early if the 'urlfetch' resource is not enabled. - open_urlresource(TESTDATAURL) run_unittest(NormalizationTest) if __name__ == "__main__": From nnorwitz at gmail.com Sun Nov 1 22:58:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 1 Nov 2009 16:58:55 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091101215855.GA24861@kbk-i386-bb.psfb.org> 334 tests OK. 1 test failed: test_normalization 1 test altered the execution environment: test_distutils 40 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 10 skips unexpected on linux2: test_multiprocessing test_codecmaps_tw test_codecmaps_cn test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_codecmaps_jp test_codecmaps_kr test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT ... test_codecmaps_cn skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT test_codecmaps_hk test_codecmaps_jp fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ... test_codecmaps_jp skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT test_codecmaps_kr fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ... test_codecmaps_kr skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT test_codecmaps_tw fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ... test_codecmaps_tw skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19567 refs] [19567 refs] [19567 refs] [19564 refs] Warning -- sys.stdout was modified by test_distutils test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15425 refs] [15425 refs] [15425 refs] [25439 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization fetching http://www.unicode.org/Public/5.1.0/ucd/NormalizationTest.txt ... test test_normalization crashed -- : [Errno socket error] [Errno 110] Connection timed out test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17013 refs] [17013 refs] test_plistlib test_poll test_popen [15430 refs] [15430 refs] [15430 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20924 refs] [20924 refs] [20924 refs] [20924 refs] [20924 refs] [20923 refs] [20923 refs] test_pyexpat test_queue test_quopri [17951 refs] [17951 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15425 refs] [15425 refs] [15428 refs] [15425 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [17286 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] . [15425 refs] [15425 refs] this bit of output is from a test of stdout in a different process ... [15425 refs] [15425 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [17286 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] . [15425 refs] [15425 refs] this bit of output is from a test of stdout in a different process ... [15425 refs] [15425 refs] [15640 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15425 refs] [15425 refs] [15654 refs] [15448 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:654: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1978: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15428 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18738 refs] [20298 refs] [20112 refs] [20112 refs] [20112 refs] [20112 refs] test_threading_local test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 334 tests OK. 1 test failed: test_normalization 1 test altered the execution environment: test_distutils 40 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 10 skips unexpected on linux2: test_multiprocessing test_codecmaps_tw test_codecmaps_cn test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_codecmaps_jp test_codecmaps_kr [880593 refs] From python-checkins at python.org Sun Nov 1 23:02:03 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 22:02:03 -0000 Subject: [Python-checkins] r76037 - python/trunk/Lib/test/test_support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 23:02:03 2009 New Revision: 76037 Log: Use a custom timeout in test_support.open_urlresource. Modified: python/trunk/Lib/test/test_support.py Modified: python/trunk/Lib/test/test_support.py ============================================================================== --- python/trunk/Lib/test/test_support.py (original) +++ python/trunk/Lib/test/test_support.py Sun Nov 1 23:02:03 2009 @@ -463,7 +463,7 @@ '', 'exec') def open_urlresource(url): - import urllib, urlparse + import urlparse, urllib2 requires('urlfetch') filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL! @@ -473,7 +473,15 @@ return open(fn) print >> get_original_stdout(), '\tfetching %s ...' % url - fn, _ = urllib.urlretrieve(url, fn) + f = urllib2.urlopen(url, timeout=15) + try: + with open(fn, "wb") as out: + s = f.read() + while s: + out.write(s) + s = f.read() + finally: + f.close() return open(fn) From python-checkins at python.org Sun Nov 1 23:06:59 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 22:06:59 -0000 Subject: [Python-checkins] r76038 - in python/branches/release26-maint: Lib/test/test_support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 23:06:59 2009 New Revision: 76038 Log: Merged revisions 76037 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76037 | antoine.pitrou | 2009-11-01 23:02:03 +0100 (dim., 01 nov. 2009) | 3 lines Use a custom timeout in test_support.open_urlresource. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_support.py Modified: python/branches/release26-maint/Lib/test/test_support.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_support.py (original) +++ python/branches/release26-maint/Lib/test/test_support.py Sun Nov 1 23:06:59 2009 @@ -378,7 +378,7 @@ testcase.fail('Missing SyntaxError: "%s"' % statement) def open_urlresource(url): - import urllib, urlparse + import urlparse, urllib2 requires('urlfetch') filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL! @@ -389,8 +389,16 @@ return open(fn) print >> get_original_stdout(), '\tfetching %s ...' % url - fn, _ = urllib.urlretrieve(url, filename) - return open(fn) + f = urllib2.urlopen(url, timeout=15) + try: + with open(filename, "wb") as out: + s = f.read() + while s: + out.write(s) + s = f.read() + finally: + f.close() + return open(filename) class WarningsRecorder(object): From python-checkins at python.org Sun Nov 1 23:07:18 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 22:07:18 -0000 Subject: [Python-checkins] r76039 - in python/branches/release31-maint: Lib/test/test_normalization.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 23:07:18 2009 New Revision: 76039 Log: Merged revisions 76036 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76036 | antoine.pitrou | 2009-11-01 22:43:20 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76033 | antoine.pitrou | 2009-11-01 22:26:14 +0100 (dim., 01 nov. 2009) | 3 lines test_normalization should skip and not crash when the resource isn't available ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_normalization.py Modified: python/branches/release31-maint/Lib/test/test_normalization.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_normalization.py (original) +++ python/branches/release31-maint/Lib/test/test_normalization.py Sun Nov 1 23:07:18 2009 @@ -40,6 +40,11 @@ class NormalizationTest(unittest.TestCase): def test_main(self): part1_data = {} + # Hit the exception early + try: + open_urlresource(TESTDATAURL, encoding="utf-8") + except IOError: + self.skipTest("Could not retrieve " + TESTDATAURL) for line in open_urlresource(TESTDATAURL, encoding="utf-8"): if '#' in line: line = line.split('#')[0] @@ -95,8 +100,6 @@ def test_main(): - # Hit the exception early - open_urlresource(TESTDATAURL) run_unittest(NormalizationTest) if __name__ == "__main__": From python-checkins at python.org Sun Nov 1 23:13:49 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 22:13:49 -0000 Subject: [Python-checkins] r76040 - in python/branches/py3k: Lib/test/support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 23:13:48 2009 New Revision: 76040 Log: Merged revisions 76037 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76037 | antoine.pitrou | 2009-11-01 23:02:03 +0100 (dim., 01 nov. 2009) | 3 lines Use a custom timeout in test_support.open_urlresource. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/support.py Modified: python/branches/py3k/Lib/test/support.py ============================================================================== --- python/branches/py3k/Lib/test/support.py (original) +++ python/branches/py3k/Lib/test/support.py Sun Nov 1 23:13:48 2009 @@ -458,10 +458,17 @@ return open(fn, *args, **kw) print('\tfetching %s ...' % url, file=get_original_stdout()) - fn, _ = urllib.request.urlretrieve(url, fn) + f = urllib.request.urlopen(url, timeout=15) + try: + with open(fn, "wb") as out: + s = f.read() + while s: + out.write(s) + s = f.read() + finally: + f.close() return open(fn, *args, **kw) - class WarningsRecorder(object): """Convenience wrapper for the warnings list returned on entry to the warnings.catch_warnings() context manager. From python-checkins at python.org Sun Nov 1 23:28:14 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 22:28:14 -0000 Subject: [Python-checkins] r76041 - in python/branches/release31-maint: Lib/test/support.py Message-ID: Author: antoine.pitrou Date: Sun Nov 1 23:28:14 2009 New Revision: 76041 Log: Merged revisions 76040 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76040 | antoine.pitrou | 2009-11-01 23:13:48 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76037 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76037 | antoine.pitrou | 2009-11-01 23:02:03 +0100 (dim., 01 nov. 2009) | 3 lines Use a custom timeout in test_support.open_urlresource. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/support.py Modified: python/branches/release31-maint/Lib/test/support.py ============================================================================== --- python/branches/release31-maint/Lib/test/support.py (original) +++ python/branches/release31-maint/Lib/test/support.py Sun Nov 1 23:28:14 2009 @@ -455,9 +455,16 @@ return open(fn, *args, **kw) print('\tfetching %s ...' % url, file=get_original_stdout()) - fn, _ = urllib.request.urlretrieve(url, filename) - return open(fn, *args, **kw) - + f = urllib.request.urlopen(url, timeout=15) + try: + with open(filename, "wb") as out: + s = f.read() + while s: + out.write(s) + s = f.read() + finally: + f.close() + return open(filename, *args, **kw) class WarningsRecorder(object): """Convenience wrapper for the warnings list returned on From python-checkins at python.org Sun Nov 1 23:33:46 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 01 Nov 2009 22:33:46 -0000 Subject: [Python-checkins] r76042 - in python/trunk/Lib/distutils/tests: test_build_py.py test_util.py Message-ID: Author: tarek.ziade Date: Sun Nov 1 23:33:45 2009 New Revision: 76042 Log: fixed stdout alteration in test_distutils Modified: python/trunk/Lib/distutils/tests/test_build_py.py python/trunk/Lib/distutils/tests/test_util.py Modified: python/trunk/Lib/distutils/tests/test_build_py.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_build_py.py (original) +++ python/trunk/Lib/distutils/tests/test_build_py.py Sun Nov 1 23:33:45 2009 @@ -69,6 +69,7 @@ open(os.path.join(testdir, "testfile"), "w").close() os.chdir(sources) + old_stdout = sys.stdout sys.stdout = StringIO.StringIO() try: @@ -87,7 +88,7 @@ finally: # Restore state. os.chdir(cwd) - sys.stdout = sys.__stdout__ + sys.stdout = old_stdout def test_dont_write_bytecode(self): # makes sure byte_compile is not used Modified: python/trunk/Lib/distutils/tests/test_util.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_util.py (original) +++ python/trunk/Lib/distutils/tests/test_util.py Sun Nov 1 23:33:45 2009 @@ -60,6 +60,8 @@ util.find_executable = self._find_executable self._exes = {} self.old_popen = subprocess.Popen + self.old_stdout = sys.stdout + self.old_stderr = sys.stderr FakePopen.test_class = self subprocess.Popen = FakePopen @@ -79,6 +81,8 @@ sysconfig._config_vars = copy(self._config_vars) util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen + sys.old_stdout = self.old_stdout + sys.old_stderr = self.old_stderr super(UtilTestCase, self).tearDown() def _set_uname(self, uname): From python-checkins at python.org Sun Nov 1 23:38:44 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 01 Nov 2009 22:38:44 -0000 Subject: [Python-checkins] r76043 - in python/branches/py3k: Lib/distutils/tests/test_build_py.py Lib/distutils/tests/test_util.py Message-ID: Author: tarek.ziade Date: Sun Nov 1 23:38:44 2009 New Revision: 76043 Log: Merged revisions 76042 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76042 | tarek.ziade | 2009-11-01 23:33:45 +0100 (Sun, 01 Nov 2009) | 1 line fixed stdout alteration in test_distutils ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_build_py.py python/branches/py3k/Lib/distutils/tests/test_util.py Modified: python/branches/py3k/Lib/distutils/tests/test_build_py.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_build_py.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_build_py.py Sun Nov 1 23:38:44 2009 @@ -69,6 +69,7 @@ open(os.path.join(testdir, "testfile"), "w").close() os.chdir(sources) + old_stdout = sys.stdout sys.stdout = io.StringIO() try: @@ -87,7 +88,7 @@ finally: # Restore state. os.chdir(cwd) - sys.stdout = sys.__stdout__ + sys.stdout = old_stdout def test_dont_write_bytecode(self): # makes sure byte_compile is not used Modified: python/branches/py3k/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_util.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_util.py Sun Nov 1 23:38:44 2009 @@ -60,6 +60,8 @@ util.find_executable = self._find_executable self._exes = {} self.old_popen = subprocess.Popen + self.old_stdout = sys.stdout + self.old_stderr = sys.stderr FakePopen.test_class = self subprocess.Popen = FakePopen @@ -79,6 +81,8 @@ sysconfig._config_vars = copy(self._config_vars) util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen + sys.old_stdout = self.old_stdout + sys.old_stderr = self.old_stderr super(UtilTestCase, self).tearDown() def _set_uname(self, uname): From python-checkins at python.org Mon Nov 2 00:04:26 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 01 Nov 2009 23:04:26 -0000 Subject: [Python-checkins] r76044 - in python/branches/release26-maint/Lib/distutils: filelist.py tests/test_filelist.py Message-ID: Author: tarek.ziade Date: Mon Nov 2 00:04:26 2009 New Revision: 76044 Log: reapplied r74493 (after #6665 fix has been backported) Modified: python/branches/release26-maint/Lib/distutils/filelist.py python/branches/release26-maint/Lib/distutils/tests/test_filelist.py Modified: python/branches/release26-maint/Lib/distutils/filelist.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/filelist.py (original) +++ python/branches/release26-maint/Lib/distutils/filelist.py Mon Nov 2 00:04:26 2009 @@ -344,7 +344,9 @@ pattern_re = '' if prefix is not None: - prefix_re = (glob_to_re(prefix))[0:-1] # ditch trailing $ + # ditch end of pattern character + empty_pattern = glob_to_re('') + prefix_re = (glob_to_re(prefix))[:-len(empty_pattern)] pattern_re = "^" + os.path.join(prefix_re, ".*" + pattern_re) else: # no prefix -- respect anchor flag if anchor: Modified: python/branches/release26-maint/Lib/distutils/tests/test_filelist.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/test_filelist.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_filelist.py Mon Nov 2 00:04:26 2009 @@ -6,15 +6,15 @@ def test_glob_to_re(self): # simple cases - self.assertEquals(glob_to_re('foo*'), 'foo[^/]*$') - self.assertEquals(glob_to_re('foo?'), 'foo[^/]$') - self.assertEquals(glob_to_re('foo??'), 'foo[^/][^/]$') + self.assertEquals(glob_to_re('foo*'), 'foo[^/]*\\Z(?ms)') + self.assertEquals(glob_to_re('foo?'), 'foo[^/]\\Z(?ms)') + self.assertEquals(glob_to_re('foo??'), 'foo[^/][^/]\\Z(?ms)') # special cases - self.assertEquals(glob_to_re(r'foo\\*'), r'foo\\\\[^/]*$') - self.assertEquals(glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*$') - self.assertEquals(glob_to_re('foo????'), r'foo[^/][^/][^/][^/]$') - self.assertEquals(glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]$') + self.assertEquals(glob_to_re(r'foo\\*'), r'foo\\\\[^/]*\Z(?ms)') + self.assertEquals(glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*\Z(?ms)') + self.assertEquals(glob_to_re('foo????'), r'foo[^/][^/][^/][^/]\Z(?ms)') + self.assertEquals(glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]\Z(?ms)') def test_suite(): return unittest.makeSuite(FileListTestCase) From python-checkins at python.org Mon Nov 2 00:11:55 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 01 Nov 2009 23:11:55 -0000 Subject: [Python-checkins] r76045 - in python/branches/release31-maint: Lib/distutils/filelist.py Lib/distutils/tests/test_build_py.py Lib/distutils/tests/test_filelist.py Message-ID: Author: tarek.ziade Date: Mon Nov 2 00:11:55 2009 New Revision: 76045 Log: reapplied r74493 (after #6665 fix has been backported) Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/filelist.py python/branches/release31-maint/Lib/distutils/tests/test_build_py.py python/branches/release31-maint/Lib/distutils/tests/test_filelist.py Modified: python/branches/release31-maint/Lib/distutils/filelist.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/filelist.py (original) +++ python/branches/release31-maint/Lib/distutils/filelist.py Mon Nov 2 00:11:55 2009 @@ -312,7 +312,9 @@ pattern_re = '' if prefix is not None: - prefix_re = (glob_to_re(prefix))[0:-1] # ditch trailing $ + # ditch end of pattern character + empty_pattern = glob_to_re('') + prefix_re = (glob_to_re(prefix))[:-len(empty_pattern)] pattern_re = "^" + os.path.join(prefix_re, ".*" + pattern_re) else: # no prefix -- respect anchor flag if anchor: Modified: python/branches/release31-maint/Lib/distutils/tests/test_build_py.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_build_py.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_build_py.py Mon Nov 2 00:11:55 2009 @@ -69,6 +69,7 @@ open(os.path.join(testdir, "testfile"), "w").close() os.chdir(sources) + old_stdout = sys.stdout sys.stdout = io.StringIO() try: @@ -87,7 +88,7 @@ finally: # Restore state. os.chdir(cwd) - sys.stdout = sys.__stdout__ + sys.stdout = old_stdout def test_dont_write_bytecode(self): # makes sure byte_compile is not used Modified: python/branches/release31-maint/Lib/distutils/tests/test_filelist.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_filelist.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_filelist.py Mon Nov 2 00:11:55 2009 @@ -9,15 +9,15 @@ def test_glob_to_re(self): # simple cases - self.assertEquals(glob_to_re('foo*'), 'foo[^/]*$') - self.assertEquals(glob_to_re('foo?'), 'foo[^/]$') - self.assertEquals(glob_to_re('foo??'), 'foo[^/][^/]$') + self.assertEquals(glob_to_re('foo*'), 'foo[^/]*\\Z(?ms)') + self.assertEquals(glob_to_re('foo?'), 'foo[^/]\\Z(?ms)') + self.assertEquals(glob_to_re('foo??'), 'foo[^/][^/]\\Z(?ms)') # special cases - self.assertEquals(glob_to_re(r'foo\\*'), r'foo\\\\[^/]*$') - self.assertEquals(glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*$') - self.assertEquals(glob_to_re('foo????'), r'foo[^/][^/][^/][^/]$') - self.assertEquals(glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]$') + self.assertEquals(glob_to_re(r'foo\\*'), r'foo\\\\[^/]*\Z(?ms)') + self.assertEquals(glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*\Z(?ms)') + self.assertEquals(glob_to_re('foo????'), r'foo[^/][^/][^/][^/]\Z(?ms)') + self.assertEquals(glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]\Z(?ms)') def test_debug_print(self): file_list = FileList() From python-checkins at python.org Mon Nov 2 00:17:51 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 01 Nov 2009 23:17:51 -0000 Subject: [Python-checkins] r76046 - in python/branches/release26-maint: Lib/distutils/tests/test_build_py.py Message-ID: Author: tarek.ziade Date: Mon Nov 2 00:17:51 2009 New Revision: 76046 Log: Merged revisions 76042 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76042 | tarek.ziade | 2009-11-01 23:33:45 +0100 (Sun, 01 Nov 2009) | 1 line fixed stdout alteration in test_distutils ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/tests/test_build_py.py Modified: python/branches/release26-maint/Lib/distutils/tests/test_build_py.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/test_build_py.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_build_py.py Mon Nov 2 00:17:51 2009 @@ -69,6 +69,7 @@ open(os.path.join(testdir, "testfile"), "w").close() os.chdir(sources) + old_stdout = sys.stdout sys.stdout = StringIO.StringIO() try: @@ -87,7 +88,7 @@ finally: # Restore state. os.chdir(cwd) - sys.stdout = sys.__stdout__ + sys.stdout = old_stdout def test_suite(): return unittest.makeSuite(BuildPyTestCase) From python-checkins at python.org Mon Nov 2 00:54:21 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 23:54:21 -0000 Subject: [Python-checkins] r76047 - python/trunk/Lib/test/test_site.py Message-ID: Author: antoine.pitrou Date: Mon Nov 2 00:54:20 2009 New Revision: 76047 Log: Fix and improve some assertions in test_site Modified: python/trunk/Lib/test/test_site.py Modified: python/trunk/Lib/test/test_site.py ============================================================================== --- python/trunk/Lib/test/test_site.py (original) +++ python/trunk/Lib/test/test_site.py Mon Nov 2 00:54:20 2009 @@ -70,9 +70,9 @@ def pth_file_tests(self, pth_file): """Contain common code for testing results of reading a .pth file""" self.assertTrue(pth_file.imported in sys.modules, - "%s not in sys.path" % pth_file.imported) - self.assertTrue(site.makepath(pth_file.good_dir_path)[0] in sys.path) - self.assertTrue(not os.path.exists(pth_file.bad_dir_path)) + "%s not in sys.modules" % pth_file.imported) + self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path) + self.assertFalse(os.path.exists(pth_file.bad_dir_path)) def test_addpackage(self): # Make sure addpackage() imports if the line starts with 'import', @@ -104,7 +104,7 @@ def test_s_option(self): usersite = site.USER_SITE - self.assertTrue(usersite in sys.path) + self.assertIn(usersite, sys.path) rc = subprocess.call([sys.executable, '-c', 'import sys; sys.exit(%r in sys.path)' % usersite]) @@ -140,7 +140,8 @@ site.USER_BASE = None with EnvironmentVarGuard() as environ: environ['PYTHONUSERBASE'] = 'xoxo' - self.assertTrue(site.getuserbase().startswith('xoxo')) + self.assertTrue(site.getuserbase().startswith('xoxo'), + site.getuserbase()) def test_getusersitepackages(self): site.USER_SITE = None @@ -149,14 +150,14 @@ # the call sets USER_BASE *and* USER_SITE self.assertEquals(site.USER_SITE, user_site) - self.assertTrue(user_site.startswith(site.USER_BASE)) + self.assertTrue(user_site.startswith(site.USER_BASE), user_site) def test_getsitepackages(self): site.PREFIXES = ['xoxo'] dirs = site.getsitepackages() if sys.platform in ('os2emx', 'riscos'): - self.assertTrue(len(dirs), 1) + self.assertEqual(len(dirs), 1) wanted = os.path.join('xoxo', 'Lib', 'site-packages') self.assertEquals(dirs[0], wanted) elif os.sep == '/': @@ -176,7 +177,7 @@ if sys.platform == "darwin": site.PREFIXES = ['Python.framework'] dirs = site.getsitepackages() - self.assertTrue(len(dirs), 4) + self.assertEqual(len(dirs), 4) wanted = os.path.join('~', 'Library', 'Python', sys.version[:3], 'site-packages') self.assertEquals(dirs[2], os.path.expanduser(wanted)) From python-checkins at python.org Mon Nov 2 00:55:41 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 01 Nov 2009 23:55:41 -0000 Subject: [Python-checkins] r76048 - in python/branches/py3k: Lib/test/test_site.py Message-ID: Author: antoine.pitrou Date: Mon Nov 2 00:55:40 2009 New Revision: 76048 Log: Merged revisions 76047 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76047 | antoine.pitrou | 2009-11-02 00:54:20 +0100 (lun., 02 nov. 2009) | 3 lines Fix and improve some assertions in test_site ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_site.py Modified: python/branches/py3k/Lib/test/test_site.py ============================================================================== --- python/branches/py3k/Lib/test/test_site.py (original) +++ python/branches/py3k/Lib/test/test_site.py Mon Nov 2 00:55:40 2009 @@ -70,9 +70,9 @@ def pth_file_tests(self, pth_file): """Contain common code for testing results of reading a .pth file""" self.assertTrue(pth_file.imported in sys.modules, - "%s not in sys.path" % pth_file.imported) - self.assertTrue(site.makepath(pth_file.good_dir_path)[0] in sys.path) - self.assertTrue(not os.path.exists(pth_file.bad_dir_path)) + "%s not in sys.modules" % pth_file.imported) + self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path) + self.assertFalse(os.path.exists(pth_file.bad_dir_path)) def test_addpackage(self): # Make sure addpackage() imports if the line starts with 'import', @@ -104,7 +104,7 @@ def test_s_option(self): usersite = site.USER_SITE - self.assertTrue(usersite in sys.path) + self.assertIn(usersite, sys.path) rc = subprocess.call([sys.executable, '-c', 'import sys; sys.exit(%r in sys.path)' % usersite]) @@ -139,7 +139,8 @@ site.USER_BASE = None with EnvironmentVarGuard() as environ: environ['PYTHONUSERBASE'] = 'xoxo' - self.assertTrue(site.getuserbase().startswith('xoxo')) + self.assertTrue(site.getuserbase().startswith('xoxo'), + site.getuserbase()) def test_getusersitepackages(self): site.USER_SITE = None @@ -148,14 +149,14 @@ # the call sets USER_BASE *and* USER_SITE self.assertEquals(site.USER_SITE, user_site) - self.assertTrue(user_site.startswith(site.USER_BASE)) + self.assertTrue(user_site.startswith(site.USER_BASE), user_site) def test_getsitepackages(self): site.PREFIXES = ['xoxo'] dirs = site.getsitepackages() if sys.platform in ('os2emx', 'riscos'): - self.assertTrue(len(dirs), 1) + self.assertEqual(len(dirs), 1) wanted = os.path.join('xoxo', 'Lib', 'site-packages') self.assertEquals(dirs[0], wanted) elif os.sep == '/': @@ -175,7 +176,7 @@ if sys.platform == "darwin": site.PREFIXES = ['Python.framework'] dirs = site.getsitepackages() - self.assertTrue(len(dirs), 4) + self.assertEqual(len(dirs), 4) wanted = os.path.join('~', 'Library', 'Python', sys.version[:3], 'site-packages') self.assertEquals(dirs[2], os.path.expanduser(wanted)) From nnorwitz at gmail.com Mon Nov 2 01:04:04 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 1 Nov 2009 19:04:04 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091102000404.GA21764@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [-84, 0, 0] references, sum=-84 test_warnings leaked [0, 0, 60] references, sum=60 Less important issues: ---------------------- test_popen2 leaked [-25, 0, 50] references, sum=25 test_ssl leaked [-420, 420, 0] references, sum=0 test_threading leaked [48, 48, 48] references, sum=144 test_zipimport_support leaked [0, -25, 25] references, sum=0 From nnorwitz at gmail.com Mon Nov 2 01:48:15 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 1 Nov 2009 19:48:15 -0500 Subject: [Python-checkins] Python Regression Test Failures all (1) Message-ID: <20091102004815.GA27579@kbk-i386-bb.psfb.org> 340 tests OK. 1 test failed: test_normalization 1 test altered the execution environment: test_distutils 31 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_codecmaps_cn test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 10 skips unexpected on linux2: test_multiprocessing test_codecmaps_tw test_codecmaps_cn test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_codecmaps_jp test_codecmaps_kr test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 Sleepycat Software: Berkeley DB 4.1.25: (December 19, 2002) Test path prefix: /tmp/z-test_bsddb3-21789 test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT ... test_codecmaps_cn skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT test_codecmaps_hk test_codecmaps_jp fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ... test_codecmaps_jp skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT test_codecmaps_kr fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ... test_codecmaps_kr skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT test_codecmaps_tw fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ... test_codecmaps_tw skipped -- Could not retrieve http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler testCompileLibrary still working, be patient... test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19564 refs] Warning -- sys.stdout was modified by test_distutils test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15425 refs] [15425 refs] [15425 refs] [25439 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization fetching http://www.unicode.org/Public/5.1.0/ucd/NormalizationTest.txt ... test test_normalization crashed -- : [Errno socket error] [Errno 110] Connection timed out test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17013 refs] [17013 refs] test_plistlib test_poll test_popen [15430 refs] [15430 refs] [15430 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20924 refs] [20924 refs] [20924 refs] [20924 refs] [20924 refs] [20923 refs] [20923 refs] test_pyexpat test_queue test_quopri [17951 refs] [17951 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15425 refs] [15425 refs] [15428 refs] [15425 refs] test_slice test_smtplib test_smtpnet test_socket test_socketserver test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [17286 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] . [15425 refs] [15425 refs] this bit of output is from a test of stdout in a different process ... [15425 refs] [15425 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [17286 refs] [15640 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] [15425 refs] . [15425 refs] [15425 refs] this bit of output is from a test of stdout in a different process ... [15425 refs] [15425 refs] [15640 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15425 refs] [15425 refs] [15654 refs] [15448 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:654: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1978: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15428 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18738 refs] [20298 refs] [20112 refs] [20112 refs] [20112 refs] [20112 refs] test_threading_local test_threadsignals test_time test_timeout test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle sh: line 1: python2.4: command not found sh: line 1: python2.6: command not found test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 340 tests OK. 1 test failed: test_normalization 1 test altered the execution environment: test_distutils 31 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_codecmaps_cn test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 10 skips unexpected on linux2: test_multiprocessing test_codecmaps_tw test_codecmaps_cn test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_codecmaps_jp test_codecmaps_kr [897056 refs] From python-checkins at python.org Mon Nov 2 01:59:52 2009 From: python-checkins at python.org (neil.schemenauer) Date: Mon, 02 Nov 2009 00:59:52 -0000 Subject: [Python-checkins] r76049 - python/branches/release26-maint/Lib/test/test_hotshot.py Message-ID: Author: neil.schemenauer Date: Mon Nov 2 01:59:52 2009 New Revision: 76049 Log: Fix broken test in test_hotshot. Treating the current directory as an empty file is sloppy and non-portable. Use NamedTemporaryFile to make an empty file. Modified: python/branches/release26-maint/Lib/test/test_hotshot.py Modified: python/branches/release26-maint/Lib/test/test_hotshot.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_hotshot.py (original) +++ python/branches/release26-maint/Lib/test/test_hotshot.py Mon Nov 2 01:59:52 2009 @@ -3,6 +3,7 @@ import os import pprint import unittest +import tempfile import _hotshot import gc @@ -127,7 +128,12 @@ os.remove(test_support.TESTFN) def test_logreader_eof_error(self): - self.assertRaises((IOError, EOFError), _hotshot.logreader, ".") + emptyfile = tempfile.NamedTemporaryFile() + try: + self.assertRaises((IOError, EOFError), _hotshot.logreader, + emptyfile.name) + finally: + emptyfile.close() gc.collect() def test_main(): From solipsis at pitrou.net Mon Nov 2 01:59:27 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Mon, 2 Nov 2009 00:59:27 +0000 (UTC) Subject: [Python-checkins] Python Regression Test Failures refleak (2) References: <20091102000404.GA21764@kbk-i386-bb.psfb.org> Message-ID: Neal Norwitz gmail.com> writes: > [snip refleak results] Neal, for what branch and what revision are those results? Thanks Antoine. From python-checkins at python.org Mon Nov 2 02:37:38 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 02 Nov 2009 01:37:38 -0000 Subject: [Python-checkins] r76050 - python/trunk/configure.in Message-ID: Author: gregory.p.smith Date: Mon Nov 2 02:37:37 2009 New Revision: 76050 Log: see http://bugs.python.org/issue1006238 this merges in the following patch to make cross compilation of the chflags check easier: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-lang/python/files/python-2.6-chflags-cross.patch?rev=1.1 Modified: python/trunk/configure.in Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Mon Nov 2 02:37:37 2009 @@ -2657,8 +2657,7 @@ # On Tru64, chflags seems to be present, but calling it will # exit Python -AC_MSG_CHECKING(for chflags) -AC_CACHE_VAL(ac_cv_have_chflags, +AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl AC_TRY_RUN([[ #include #include @@ -2670,16 +2669,16 @@ } ]], ac_cv_have_chflags=yes, ac_cv_have_chflags=no, - ac_cv_have_chflags=no) -) -AC_MSG_RESULT($ac_cv_have_chflags) -if test $ac_cv_have_chflags = yes -then + ac_cv_have_chflags=cross) +]) +if test "$ac_cv_have_chflags" = cross ; then + AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) +fi +if test "$ac_cv_have_chflags" = yes ; then AC_DEFINE(HAVE_CHFLAGS, 1, Define to 1 if you have the `chflags' function.) fi -AC_MSG_CHECKING(for lchflags) -AC_CACHE_VAL(ac_cv_have_lchflags, +AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl AC_TRY_RUN([[ #include #include @@ -2691,11 +2690,12 @@ } ]], ac_cv_have_lchflags=yes, ac_cv_have_lchflags=no, - ac_cv_have_lchflags=no) -) -AC_MSG_RESULT($ac_cv_have_lchflags) -if test $ac_cv_have_lchflags = yes -then + ac_cv_have_lchflags=cross) +]) +if test "$ac_cv_have_lchflags" = cross ; then + AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) +fi +if test "$ac_cv_have_lchflags" = yes ; then AC_DEFINE(HAVE_LCHFLAGS, 1, Define to 1 if you have the `lchflags' function.) fi From python-checkins at python.org Mon Nov 2 02:38:35 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 02 Nov 2009 01:38:35 -0000 Subject: [Python-checkins] r76051 - python/trunk/configure Message-ID: Author: gregory.p.smith Date: Mon Nov 2 02:38:35 2009 New Revision: 76051 Log: build using r76050 Modified: python/trunk/configure Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Mon Nov 2 02:38:35 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76028 . +# From configure.in Revision: 76050 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -18763,7 +18763,7 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then - ac_cv_have_chflags=no + ac_cv_have_chflags=cross else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -18771,7 +18771,7 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - +[ #include #include int main(int argc, char*argv[]) @@ -18780,7 +18780,7 @@ return 1; return 0; } - +] _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" @@ -18817,11 +18817,98 @@ fi - { echo "$as_me:$LINENO: result: $ac_cv_have_chflags" >&5 echo "${ECHO_T}$ac_cv_have_chflags" >&6; } -if test $ac_cv_have_chflags = yes -then +if test "$ac_cv_have_chflags" = cross ; then + { echo "$as_me:$LINENO: checking for chflags" >&5 +echo $ECHO_N "checking for chflags... $ECHO_C" >&6; } +if test "${ac_cv_func_chflags+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define chflags to an innocuous variant, in case declares chflags. + For example, HP-UX 11i declares gettimeofday. */ +#define chflags innocuous_chflags + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char chflags (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef chflags + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char chflags (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_chflags || defined __stub___chflags +choke me +#endif + +int +main () +{ +return chflags (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_chflags=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_chflags=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_chflags" >&5 +echo "${ECHO_T}$ac_cv_func_chflags" >&6; } +if test $ac_cv_func_chflags = yes; then + ac_cv_have_chflags="yes" +else + ac_cv_have_chflags="no" +fi + +fi +if test "$ac_cv_have_chflags" = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_CHFLAGS 1 @@ -18835,7 +18922,7 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then - ac_cv_have_lchflags=no + ac_cv_have_lchflags=cross else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -18843,7 +18930,7 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - +[ #include #include int main(int argc, char*argv[]) @@ -18852,7 +18939,7 @@ return 1; return 0; } - +] _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" @@ -18889,11 +18976,98 @@ fi - { echo "$as_me:$LINENO: result: $ac_cv_have_lchflags" >&5 echo "${ECHO_T}$ac_cv_have_lchflags" >&6; } -if test $ac_cv_have_lchflags = yes -then +if test "$ac_cv_have_lchflags" = cross ; then + { echo "$as_me:$LINENO: checking for lchflags" >&5 +echo $ECHO_N "checking for lchflags... $ECHO_C" >&6; } +if test "${ac_cv_func_lchflags+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define lchflags to an innocuous variant, in case declares lchflags. + For example, HP-UX 11i declares gettimeofday. */ +#define lchflags innocuous_lchflags + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char lchflags (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef lchflags + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char lchflags (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_lchflags || defined __stub___lchflags +choke me +#endif + +int +main () +{ +return lchflags (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_lchflags=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_lchflags=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_lchflags" >&5 +echo "${ECHO_T}$ac_cv_func_lchflags" >&6; } +if test $ac_cv_func_lchflags = yes; then + ac_cv_have_lchflags="yes" +else + ac_cv_have_lchflags="no" +fi + +fi +if test "$ac_cv_have_lchflags" = yes ; then cat >>confdefs.h <<\_ACEOF #define HAVE_LCHFLAGS 1 From python-checkins at python.org Mon Nov 2 03:02:38 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 02 Nov 2009 02:02:38 -0000 Subject: [Python-checkins] r76052 - python/trunk/configure.in Message-ID: Author: gregory.p.smith Date: Mon Nov 2 03:02:38 2009 New Revision: 76052 Log: see issue1006238, this merges in the following patch to ease cross compiling the printf %zd check. http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-lang/python/files/python-2.5-cross-printf.patch?rev=1.1&view=markup Modified: python/trunk/configure.in Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Mon Nov 2 03:02:38 2009 @@ -3953,9 +3953,8 @@ AC_MSG_RESULT(no) fi -AC_MSG_CHECKING(for %zd printf() format support) -AC_CACHE_VAL(ac_cv_have_size_t_format, -AC_TRY_RUN([[ +AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl +AC_TRY_RUN([ #include #include #include @@ -3990,13 +3989,11 @@ return 0; } -]], ac_cv_have_size_t_format=yes, +], ac_cv_have_size_t_format=yes, ac_cv_have_size_t_format=no, - ac_cv_have_size_t_format=no) -) -AC_MSG_RESULT($ac_cv_have_size_t_format) -if test $ac_cv_have_size_t_format = yes -then + [ac_cv_have_size_t_format="cross -- assuming yes"] +)]) +if test "$ac_cv_have_size_t_format" != no ; then AC_DEFINE(PY_FORMAT_SIZE_T, "z", [Define to printf format modifier for Py_ssize_t]) fi From python-checkins at python.org Mon Nov 2 03:03:17 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 02 Nov 2009 02:03:17 -0000 Subject: [Python-checkins] r76053 - python/trunk/configure Message-ID: Author: gregory.p.smith Date: Mon Nov 2 03:03:16 2009 New Revision: 76053 Log: regenerated from r76052 Modified: python/trunk/configure Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Mon Nov 2 03:03:16 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76050 . +# From configure.in Revision: 76052 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -27021,7 +27021,8 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then - ac_cv_have_size_t_format=no + ac_cv_have_size_t_format="cross -- assuming yes" + else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -27099,13 +27100,10 @@ fi - fi - { echo "$as_me:$LINENO: result: $ac_cv_have_size_t_format" >&5 echo "${ECHO_T}$ac_cv_have_size_t_format" >&6; } -if test $ac_cv_have_size_t_format = yes -then +if test "$ac_cv_have_size_t_format" != no ; then cat >>confdefs.h <<\_ACEOF #define PY_FORMAT_SIZE_T "z" From nnorwitz at gmail.com Mon Nov 2 11:46:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 2 Nov 2009 05:46:55 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091102104655.GA3844@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [420, 339, 0] references, sum=759 Less important issues: ---------------------- test_threading leaked [48, 48, 48] references, sum=144 From python-checkins at python.org Mon Nov 2 12:34:27 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 11:34:27 -0000 Subject: [Python-checkins] r76054 - python/trunk/Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 2 12:34:27 2009 New Revision: 76054 Log: Since r76034 was successful, add a NEWS entry for it. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Nov 2 12:34:27 2009 @@ -426,6 +426,10 @@ Library ------- +- Issue #6896: mailbox.Maildir now invalidates its internal cache each time + a modification is done through it. This fixes inconsistencies and test + failures on systems with slightly bogus mtime behaviour. + - Issue #7246 & Issue #7208: getpass now properly flushes input before reading from stdin so that existing input does not confuse it and lead to incorrect entry or an IOError. It also properly flushes it From python-checkins at python.org Mon Nov 2 12:36:52 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 11:36:52 -0000 Subject: [Python-checkins] r76055 - in python/branches/py3k: Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 2 12:36:51 2009 New Revision: 76055 Log: Merged revisions 76034,76054 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76034 | antoine.pitrou | 2009-11-01 22:29:33 +0100 (dim., 01 nov. 2009) | 3 lines This should finally fix #6896. Let's watch the buildbots. ........ r76054 | antoine.pitrou | 2009-11-02 12:34:27 +0100 (lun., 02 nov. 2009) | 3 lines Since r76034 was successful, add a NEWS entry for it. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/mailbox.py python/branches/py3k/Lib/test/test_mailbox.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/mailbox.py ============================================================================== --- python/branches/py3k/Lib/mailbox.py (original) +++ python/branches/py3k/Lib/mailbox.py Mon Nov 2 12:36:51 2009 @@ -234,6 +234,9 @@ raise NoSuchMailboxError(self._path) self._toc = {} self._last_read = None # Records last time we read cur/new + # NOTE: we manually invalidate _last_read each time we do any + # modifications ourselves, otherwise we might get tripped up by + # bogus mtime behaviour on some systems (see issue #6896). def add(self, message): """Add message and return assigned key.""" @@ -267,11 +270,15 @@ raise if isinstance(message, MaildirMessage): os.utime(dest, (os.path.getatime(dest), message.get_date())) + # Invalidate cached toc + self._last_read = None return uniq def remove(self, key): """Remove the keyed message; raise KeyError if it doesn't exist.""" os.remove(os.path.join(self._path, self._lookup(key))) + # Invalidate cached toc (only on success) + self._last_read = None def discard(self, key): """If the keyed message exists, remove it.""" @@ -306,6 +313,8 @@ if isinstance(message, MaildirMessage): os.utime(new_path, (os.path.getatime(new_path), message.get_date())) + # Invalidate cached toc + self._last_read = None def get_message(self, key): """Return a Message representation or raise a KeyError.""" @@ -360,7 +369,9 @@ def flush(self): """Write any pending changes to disk.""" - return # Maildir changes are always written immediately. + # Maildir changes are always written immediately, so there's nothing + # to do except invalidate our cached toc. + self._last_read = None def lock(self): """Lock the mailbox.""" Modified: python/branches/py3k/Lib/test/test_mailbox.py ============================================================================== --- python/branches/py3k/Lib/test/test_mailbox.py (original) +++ python/branches/py3k/Lib/test/test_mailbox.py Mon Nov 2 12:36:51 2009 @@ -673,6 +673,9 @@ self.assertEqual(self._box._lookup(key0), os.path.join('new', key0)) os.remove(os.path.join(self._path, 'new', key0)) self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)}) + # Be sure that the TOC is read back from disk (see issue #6896 + # about bad mtime behaviour on some systems). + self._box.flush() self.assertRaises(KeyError, lambda: self._box._lookup(key0)) self.assertEqual(self._box._toc, {}) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 2 12:36:51 2009 @@ -123,6 +123,10 @@ Library ------- +- Issue #6896: mailbox.Maildir now invalidates its internal cache each time + a modification is done through it. This fixes inconsistencies and test + failures on systems with slightly bogus mtime behaviour. + - Issue #7246 & Issue #7208: getpass now properly flushes input before reading from stdin so that existing input does not confuse it and lead to incorrect entry or an IOError. It also properly flushes it From python-checkins at python.org Mon Nov 2 12:40:19 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 11:40:19 -0000 Subject: [Python-checkins] r76056 - in python/branches/release31-maint: Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 2 12:40:19 2009 New Revision: 76056 Log: Merged revisions 76055 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76055 | antoine.pitrou | 2009-11-02 12:36:51 +0100 (lun., 02 nov. 2009) | 13 lines Merged revisions 76034,76054 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76034 | antoine.pitrou | 2009-11-01 22:29:33 +0100 (dim., 01 nov. 2009) | 3 lines This should finally fix #6896. Let's watch the buildbots. ........ r76054 | antoine.pitrou | 2009-11-02 12:34:27 +0100 (lun., 02 nov. 2009) | 3 lines Since r76034 was successful, add a NEWS entry for it. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/mailbox.py python/branches/release31-maint/Lib/test/test_mailbox.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/mailbox.py ============================================================================== --- python/branches/release31-maint/Lib/mailbox.py (original) +++ python/branches/release31-maint/Lib/mailbox.py Mon Nov 2 12:40:19 2009 @@ -234,6 +234,9 @@ raise NoSuchMailboxError(self._path) self._toc = {} self._last_read = None # Records last time we read cur/new + # NOTE: we manually invalidate _last_read each time we do any + # modifications ourselves, otherwise we might get tripped up by + # bogus mtime behaviour on some systems (see issue #6896). def add(self, message): """Add message and return assigned key.""" @@ -267,11 +270,15 @@ raise if isinstance(message, MaildirMessage): os.utime(dest, (os.path.getatime(dest), message.get_date())) + # Invalidate cached toc + self._last_read = None return uniq def remove(self, key): """Remove the keyed message; raise KeyError if it doesn't exist.""" os.remove(os.path.join(self._path, self._lookup(key))) + # Invalidate cached toc (only on success) + self._last_read = None def discard(self, key): """If the keyed message exists, remove it.""" @@ -306,6 +313,8 @@ if isinstance(message, MaildirMessage): os.utime(new_path, (os.path.getatime(new_path), message.get_date())) + # Invalidate cached toc + self._last_read = None def get_message(self, key): """Return a Message representation or raise a KeyError.""" @@ -360,7 +369,9 @@ def flush(self): """Write any pending changes to disk.""" - return # Maildir changes are always written immediately. + # Maildir changes are always written immediately, so there's nothing + # to do except invalidate our cached toc. + self._last_read = None def lock(self): """Lock the mailbox.""" Modified: python/branches/release31-maint/Lib/test/test_mailbox.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_mailbox.py (original) +++ python/branches/release31-maint/Lib/test/test_mailbox.py Mon Nov 2 12:40:19 2009 @@ -673,6 +673,9 @@ self.assertEqual(self._box._lookup(key0), os.path.join('new', key0)) os.remove(os.path.join(self._path, 'new', key0)) self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)}) + # Be sure that the TOC is read back from disk (see issue #6896 + # about bad mtime behaviour on some systems). + self._box.flush() self.assertRaises(KeyError, lambda: self._box._lookup(key0)) self.assertEqual(self._box._toc, {}) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Nov 2 12:40:19 2009 @@ -40,6 +40,10 @@ Library ------- +- Issue #6896: mailbox.Maildir now invalidates its internal cache each time + a modification is done through it. This fixes inconsistencies and test + failures on systems with slightly bogus mtime behaviour. + - Issue #6665: Fix fnmatch to properly match filenames with newlines in them. - Issue #7246 & Issue #7208: getpass now properly flushes input before From python-checkins at python.org Mon Nov 2 16:06:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 15:06:45 -0000 Subject: [Python-checkins] r76057 - python/trunk/Objects/listobject.c Message-ID: Author: benjamin.peterson Date: Mon Nov 2 16:06:45 2009 New Revision: 76057 Log: prevent a rather unlikely segfault Modified: python/trunk/Objects/listobject.c Modified: python/trunk/Objects/listobject.c ============================================================================== --- python/trunk/Objects/listobject.c (original) +++ python/trunk/Objects/listobject.c Mon Nov 2 16:06:45 2009 @@ -183,9 +183,12 @@ return NULL; } if (i < 0 || i >= Py_SIZE(op)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyString_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } @@ -447,9 +450,12 @@ list_item(PyListObject *a, Py_ssize_t i) { if (i < 0 || i >= Py_SIZE(a)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyString_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } From python-checkins at python.org Mon Nov 2 17:14:20 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 16:14:20 -0000 Subject: [Python-checkins] r76058 - python/trunk/Objects/listobject.c Message-ID: Author: benjamin.peterson Date: Mon Nov 2 17:14:19 2009 New Revision: 76058 Log: grant list.index() a more informative error message #7252 Modified: python/trunk/Objects/listobject.c Modified: python/trunk/Objects/listobject.c ============================================================================== --- python/trunk/Objects/listobject.c (original) +++ python/trunk/Objects/listobject.c Mon Nov 2 17:14:19 2009 @@ -2276,7 +2276,8 @@ listindex(PyListObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v; + PyObject *v, *format_tuple, *err_string; + static PyObject *err_format = NULL; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, _PyEval_SliceIndex, &start, @@ -2299,7 +2300,20 @@ else if (cmp < 0) return NULL; } - PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list"); + if (err_format == NULL) { + err_format = PyString_FromString("%r is not in list"); + if (err_format == NULL) + return NULL; + } + format_tuple = PyTuple_Pack(1, v); + if (format_tuple == NULL) + return NULL; + err_string = PyString_Format(err_format, format_tuple); + Py_DECREF(format_tuple); + if (err_string == NULL) + return NULL; + PyErr_SetObject(PyExc_ValueError, err_string); + Py_DECREF(err_string); return NULL; } From python-checkins at python.org Mon Nov 2 18:43:48 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 17:43:48 -0000 Subject: [Python-checkins] r76059 - sandbox/trunk/2to3/lib2to3/pytree.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 18:43:47 2009 New Revision: 76059 Log: tuples are no longer used for children Modified: sandbox/trunk/2to3/lib2to3/pytree.py Modified: sandbox/trunk/2to3/lib2to3/pytree.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/pytree.py (original) +++ sandbox/trunk/2to3/lib2to3/pytree.py Mon Nov 2 18:43:47 2009 @@ -45,7 +45,6 @@ # Default values for instance variables type = None # int: token number (< 256) or symbol number (>= 256) parent = None # Parent node pointer, or None - children = () # Tuple of subnodes was_changed = False def __new__(cls, *args, **kwds): From python-checkins at python.org Mon Nov 2 18:55:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 17:55:40 -0000 Subject: [Python-checkins] r76060 - sandbox/trunk/2to3/lib2to3/pytree.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 18:55:40 2009 New Revision: 76060 Log: revert r76059; apparently some fixers rely on Leaf no () for children Modified: sandbox/trunk/2to3/lib2to3/pytree.py Modified: sandbox/trunk/2to3/lib2to3/pytree.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/pytree.py (original) +++ sandbox/trunk/2to3/lib2to3/pytree.py Mon Nov 2 18:55:40 2009 @@ -45,6 +45,7 @@ # Default values for instance variables type = None # int: token number (< 256) or symbol number (>= 256) parent = None # Parent node pointer, or None + children = () # Tuple of subnodes was_changed = False def __new__(cls, *args, **kwds): From python-checkins at python.org Mon Nov 2 19:06:17 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:06:17 -0000 Subject: [Python-checkins] r76061 - in sandbox/trunk/2to3/lib2to3: fixes/fix_tuple_params.py tests/test_fixers.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:06:17 2009 New Revision: 76061 Log: make fix_tuple_params keep the tree valid #7253 Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_tuple_params.py sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_tuple_params.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_tuple_params.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_tuple_params.py Mon Nov 2 19:06:17 2009 @@ -96,6 +96,8 @@ new_lines[0].prefix = indent after = start + 1 + for line in new_lines: + line.parent = suite[0] suite[0].children[after:after] = new_lines for i in range(after+1, after+len(new_lines)+1): suite[0].children[i].prefix = indent Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Mon Nov 2 19:06:17 2009 @@ -339,6 +339,12 @@ a = "from functools import reduce\nreduce(a, b, c)" self.check(b, a) + def test_bug_7253(self): + # fix_tuple_params was being bad and orphaning nodes in the tree. + b = "def x(arg): reduce(sum, [])" + a = "from functools import reduce\ndef x(arg): reduce(sum, [])" + self.check(b, a) + def test_call_with_lambda(self): b = "reduce(lambda x, y: x + y, seq)" a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" From python-checkins at python.org Mon Nov 2 19:12:12 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:12:12 -0000 Subject: [Python-checkins] r76062 - in python/trunk/Lib/lib2to3: Grammar.txt fixes/fix_idioms.py fixes/fix_map.py fixes/fix_tuple_params.py pgen2/pgen.py pgen2/tokenize.py pytree.py tests/test_all_fixers.py tests/test_fixers.py tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:12:12 2009 New Revision: 76062 Log: Merged revisions 74359,75081,75088,75213,75278,75303,75427-75428,75734-75736,75865,76059-76061 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r74359 | benjamin.peterson | 2009-08-12 17:23:13 -0500 (Wed, 12 Aug 2009) | 1 line don't pass the deprecated print_function option ........ r75081 | benjamin.peterson | 2009-09-26 22:02:57 -0500 (Sat, 26 Sep 2009) | 1 line let 2to3 work with extended iterable unpacking ........ r75088 | benjamin.peterson | 2009-09-27 11:25:21 -0500 (Sun, 27 Sep 2009) | 1 line look on the type only for __call__ ........ r75213 | benjamin.peterson | 2009-10-03 10:09:46 -0500 (Sat, 03 Oct 2009) | 5 lines revert 75212; it's not correct People can use isinstance(x, collections.Callable) if they expect objects with __call__ in their instance dictionaries. ........ r75278 | benjamin.peterson | 2009-10-07 16:25:56 -0500 (Wed, 07 Oct 2009) | 4 lines fix whitespace problems with fix_idioms #3563 Patch by Joe Amenta. ........ r75303 | benjamin.peterson | 2009-10-09 16:59:11 -0500 (Fri, 09 Oct 2009) | 1 line port latin-1 and utf-8 cookie improvements ........ r75427 | benjamin.peterson | 2009-10-14 20:35:57 -0500 (Wed, 14 Oct 2009) | 1 line force floor division ........ r75428 | benjamin.peterson | 2009-10-14 20:39:21 -0500 (Wed, 14 Oct 2009) | 1 line silence -3 warnings about __hash__ ........ r75734 | benjamin.peterson | 2009-10-26 16:25:53 -0500 (Mon, 26 Oct 2009) | 2 lines warn on map(None, ...) with more than 2 arguments #7203 ........ r75735 | benjamin.peterson | 2009-10-26 16:28:25 -0500 (Mon, 26 Oct 2009) | 1 line remove unused result ........ r75736 | benjamin.peterson | 2009-10-26 16:29:02 -0500 (Mon, 26 Oct 2009) | 1 line using get() here is a bit pointless ........ r75865 | benjamin.peterson | 2009-10-27 15:49:00 -0500 (Tue, 27 Oct 2009) | 1 line explain reason for warning ........ r76059 | benjamin.peterson | 2009-11-02 11:43:47 -0600 (Mon, 02 Nov 2009) | 1 line tuples are no longer used for children ........ r76060 | benjamin.peterson | 2009-11-02 11:55:40 -0600 (Mon, 02 Nov 2009) | 1 line revert r76059; apparently some fixers rely on Leaf no () for children ........ r76061 | benjamin.peterson | 2009-11-02 12:06:17 -0600 (Mon, 02 Nov 2009) | 1 line make fix_tuple_params keep the tree valid #7253 ........ Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/Grammar.txt python/trunk/Lib/lib2to3/fixes/fix_idioms.py python/trunk/Lib/lib2to3/fixes/fix_map.py python/trunk/Lib/lib2to3/fixes/fix_tuple_params.py python/trunk/Lib/lib2to3/pgen2/pgen.py python/trunk/Lib/lib2to3/pgen2/tokenize.py python/trunk/Lib/lib2to3/pytree.py python/trunk/Lib/lib2to3/tests/test_all_fixers.py python/trunk/Lib/lib2to3/tests/test_fixers.py python/trunk/Lib/lib2to3/tests/test_parser.py Modified: python/trunk/Lib/lib2to3/Grammar.txt ============================================================================== --- python/trunk/Lib/lib2to3/Grammar.txt (original) +++ python/trunk/Lib/lib2to3/Grammar.txt Mon Nov 2 19:12:12 2009 @@ -53,8 +53,9 @@ simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt) -expr_stmt: testlist (augassign (yield_expr|testlist) | - ('=' (yield_expr|testlist))*) +expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) +testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter @@ -112,6 +113,7 @@ not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +star_expr: '*' expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* @@ -125,14 +127,14 @@ '{' [dictsetmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ | '.' '.' '.') -listmaker: test ( comp_for | (',' test)* [','] ) -testlist_gexp: test ( comp_for | (',' test)* [','] ) +listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_gexp: test ( comp_for | (',' (test|star_expr))* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] -exprlist: expr (',' expr)* [','] +exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | (test (comp_for | (',' test)* [','])) ) Modified: python/trunk/Lib/lib2to3/fixes/fix_idioms.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_idioms.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_idioms.py Mon Nov 2 19:12:12 2009 @@ -29,7 +29,7 @@ # Local imports from .. import fixer_base -from ..fixer_util import Call, Comma, Name, Node, syms +from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" TYPE = "power< 'type' trailer< '(' x=any ')' > >" @@ -130,5 +130,24 @@ else: raise RuntimeError("should not have reached here") sort_stmt.remove() - if next_stmt: - next_stmt[0].prefix = sort_stmt.prefix + + btwn = sort_stmt.prefix + # Keep any prefix lines between the sort_stmt and the list_call and + # shove them right after the sorted() call. + if u"\n" in btwn: + if next_stmt: + # The new prefix should be everything from the sort_stmt's + # prefix up to the last newline, then the old prefix after a new + # line. + prefix_lines = (btwn.rpartition(u"\n")[0], next_stmt[0].prefix) + next_stmt[0].prefix = u"\n".join(prefix_lines) + else: + assert list_call.parent + assert list_call.next_sibling is None + # Put a blank line after list_call and set its prefix. + end_line = BlankLine() + list_call.parent.append_child(end_line) + assert list_call.next_sibling is end_line + # The new prefix should be everything up to the first new line + # of sort_stmt's prefix. + end_line.prefix = btwn.rpartition(u"\n")[0] Modified: python/trunk/Lib/lib2to3/fixes/fix_map.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_map.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_map.py Mon Nov 2 19:12:12 2009 @@ -49,8 +49,7 @@ > | power< - 'map' - args=trailer< '(' [any] ')' > + 'map' trailer< '(' [arglist=any] ')' > > """ @@ -66,13 +65,22 @@ new.prefix = u"" new = Call(Name(u"list"), [new]) elif "map_lambda" in results: - new = ListComp(results.get("xp").clone(), - results.get("fp").clone(), - results.get("it").clone()) + new = ListComp(results["xp"].clone(), + results["fp"].clone(), + results["it"].clone()) else: if "map_none" in results: new = results["arg"].clone() else: + if "arglist" in results: + args = results["arglist"] + if args.type == syms.arglist and \ + args.children[0].type == token.NAME and \ + args.children[0].value == "None": + self.warning(node, "cannot convert map(None, ...) " + "with multiple arguments because map() " + "now truncates to the shortest sequence") + return if in_special_context(node): return None new = node.clone() Modified: python/trunk/Lib/lib2to3/fixes/fix_tuple_params.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_tuple_params.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_tuple_params.py Mon Nov 2 19:12:12 2009 @@ -96,6 +96,8 @@ new_lines[0].prefix = indent after = start + 1 + for line in new_lines: + line.parent = suite[0] suite[0].children[after:after] = new_lines for i in range(after+1, after+len(new_lines)+1): suite[0].children[i].prefix = indent Modified: python/trunk/Lib/lib2to3/pgen2/pgen.py ============================================================================== --- python/trunk/Lib/lib2to3/pgen2/pgen.py (original) +++ python/trunk/Lib/lib2to3/pgen2/pgen.py Mon Nov 2 19:12:12 2009 @@ -379,6 +379,8 @@ return False return True + __hash__ = None # For Py3 compatibility. + def generate_grammar(filename="Grammar.txt"): p = ParserGenerator(filename) return p.make_grammar() Modified: python/trunk/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- python/trunk/Lib/lib2to3/pgen2/tokenize.py (original) +++ python/trunk/Lib/lib2to3/pgen2/tokenize.py Mon Nov 2 19:12:12 2009 @@ -229,6 +229,17 @@ cookie_re = re.compile("coding[:=]\s*([-\w.]+)") +def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + def detect_encoding(readline): """ The detect_encoding() function is used to detect the encoding that should @@ -263,7 +274,7 @@ matches = cookie_re.findall(line_string) if not matches: return None - encoding = matches[0] + encoding = _get_normal_name(matches[0]) try: codec = lookup(encoding) except LookupError: @@ -373,7 +384,7 @@ column = 0 while pos < max: # measure leading whitespace if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize + elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize elif line[pos] == '\f': column = 0 else: break pos = pos + 1 Modified: python/trunk/Lib/lib2to3/pytree.py ============================================================================== --- python/trunk/Lib/lib2to3/pytree.py (original) +++ python/trunk/Lib/lib2to3/pytree.py Mon Nov 2 19:12:12 2009 @@ -63,6 +63,8 @@ return NotImplemented return self._eq(other) + __hash__ = None # For Py3 compatibility. + def __ne__(self, other): """ Compare two nodes for inequality. Modified: python/trunk/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/trunk/Lib/lib2to3/tests/test_all_fixers.py Mon Nov 2 19:12:12 2009 @@ -15,8 +15,7 @@ class Test_all(support.TestCase): def setUp(self): - options = {"print_function" : False} - self.refactor = support.get_refactorer(options=options) + self.refactor = support.get_refactorer() def test_all_project_files(self): for filepath in support.all_project_files(): Modified: python/trunk/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_fixers.py (original) +++ python/trunk/Lib/lib2to3/tests/test_fixers.py Mon Nov 2 19:12:12 2009 @@ -339,6 +339,12 @@ a = "from functools import reduce\nreduce(a, b, c)" self.check(b, a) + def test_bug_7253(self): + # fix_tuple_params was being bad and orphaning nodes in the tree. + b = "def x(arg): reduce(sum, [])" + a = "from functools import reduce\ndef x(arg): reduce(sum, [])" + self.check(b, a) + def test_call_with_lambda(self): b = "reduce(lambda x, y: x + y, seq)" a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" @@ -2834,6 +2840,11 @@ a = """x = list(map(f, 'abc')) # foo""" self.check(b, a) + def test_None_with_multiple_arguments(self): + s = """x = map(None, a, b, c)""" + self.warns_unchanged(s, "cannot convert map(None, ...) with " + "multiple arguments") + def test_map_basic(self): b = """x = map(f, 'abc')""" a = """x = list(map(f, 'abc'))""" @@ -2847,10 +2858,6 @@ a = """x = list('abc')""" self.check(b, a) - b = """x = map(None, 'abc', 'def')""" - a = """x = list(map(None, 'abc', 'def'))""" - self.check(b, a) - b = """x = map(lambda x: x+1, range(4))""" a = """x = [x+1 for x in range(4)]""" self.check(b, a) @@ -3238,6 +3245,46 @@ """ self.check(b, a) + b = r""" + try: + m = list(s) + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + except: pass + """ + self.check(b, a) + + b = r""" + try: + m = list(s) + # foo + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + # foo + except: pass + """ + self.check(b, a) + + b = r""" + m = list(s) + # more comments + m.sort()""" + + a = r""" + m = sorted(s) + # more comments""" + self.check(b, a) + def test_sort_simple_expr(self): b = """ v = t Modified: python/trunk/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_parser.py (original) +++ python/trunk/Lib/lib2to3/tests/test_parser.py Mon Nov 2 19:12:12 2009 @@ -161,6 +161,11 @@ if diff(filepath, new): self.fail("Idempotency failed: %s" % filepath) + def test_extended_unpacking(self): + driver.parse_string("a, *b, c = x\n") + driver.parse_string("[*a, b] = x\n") + driver.parse_string("(z, *y, w) = m\n") + driver.parse_string("for *z, m in d: pass\n") class TestLiterals(GrammarTest): From python-checkins at python.org Mon Nov 2 19:16:28 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:16:28 -0000 Subject: [Python-checkins] r76063 - in python/branches/py3k: Lib/lib2to3/Grammar.txt Lib/lib2to3/fixes/fix_idioms.py Lib/lib2to3/fixes/fix_map.py Lib/lib2to3/fixes/fix_tuple_params.py Lib/lib2to3/pgen2/pgen.py Lib/lib2to3/pgen2/tokenize.py Lib/lib2to3/pytree.py Lib/lib2to3/tests/test_all_fixers.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:16:28 2009 New Revision: 76063 Log: Merged revisions 76062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76062 | benjamin.peterson | 2009-11-02 12:12:12 -0600 (Mon, 02 Nov 2009) | 70 lines Merged revisions 74359,75081,75088,75213,75278,75303,75427-75428,75734-75736,75865,76059-76061 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r74359 | benjamin.peterson | 2009-08-12 17:23:13 -0500 (Wed, 12 Aug 2009) | 1 line don't pass the deprecated print_function option ........ r75081 | benjamin.peterson | 2009-09-26 22:02:57 -0500 (Sat, 26 Sep 2009) | 1 line let 2to3 work with extended iterable unpacking ........ r75088 | benjamin.peterson | 2009-09-27 11:25:21 -0500 (Sun, 27 Sep 2009) | 1 line look on the type only for __call__ ........ r75213 | benjamin.peterson | 2009-10-03 10:09:46 -0500 (Sat, 03 Oct 2009) | 5 lines revert 75212; it's not correct People can use isinstance(x, collections.Callable) if they expect objects with __call__ in their instance dictionaries. ........ r75278 | benjamin.peterson | 2009-10-07 16:25:56 -0500 (Wed, 07 Oct 2009) | 4 lines fix whitespace problems with fix_idioms #3563 Patch by Joe Amenta. ........ r75303 | benjamin.peterson | 2009-10-09 16:59:11 -0500 (Fri, 09 Oct 2009) | 1 line port latin-1 and utf-8 cookie improvements ........ r75427 | benjamin.peterson | 2009-10-14 20:35:57 -0500 (Wed, 14 Oct 2009) | 1 line force floor division ........ r75428 | benjamin.peterson | 2009-10-14 20:39:21 -0500 (Wed, 14 Oct 2009) | 1 line silence -3 warnings about __hash__ ........ r75734 | benjamin.peterson | 2009-10-26 16:25:53 -0500 (Mon, 26 Oct 2009) | 2 lines warn on map(None, ...) with more than 2 arguments #7203 ........ r75735 | benjamin.peterson | 2009-10-26 16:28:25 -0500 (Mon, 26 Oct 2009) | 1 line remove unused result ........ r75736 | benjamin.peterson | 2009-10-26 16:29:02 -0500 (Mon, 26 Oct 2009) | 1 line using get() here is a bit pointless ........ r75865 | benjamin.peterson | 2009-10-27 15:49:00 -0500 (Tue, 27 Oct 2009) | 1 line explain reason for warning ........ r76059 | benjamin.peterson | 2009-11-02 11:43:47 -0600 (Mon, 02 Nov 2009) | 1 line tuples are no longer used for children ........ r76060 | benjamin.peterson | 2009-11-02 11:55:40 -0600 (Mon, 02 Nov 2009) | 1 line revert r76059; apparently some fixers rely on Leaf no () for children ........ r76061 | benjamin.peterson | 2009-11-02 12:06:17 -0600 (Mon, 02 Nov 2009) | 1 line make fix_tuple_params keep the tree valid #7253 ........ ................ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/lib2to3/Grammar.txt python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py python/branches/py3k/Lib/lib2to3/fixes/fix_map.py python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py python/branches/py3k/Lib/lib2to3/pgen2/pgen.py python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py python/branches/py3k/Lib/lib2to3/pytree.py python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py python/branches/py3k/Lib/lib2to3/tests/test_fixers.py python/branches/py3k/Lib/lib2to3/tests/test_parser.py Modified: python/branches/py3k/Lib/lib2to3/Grammar.txt ============================================================================== --- python/branches/py3k/Lib/lib2to3/Grammar.txt (original) +++ python/branches/py3k/Lib/lib2to3/Grammar.txt Mon Nov 2 19:16:28 2009 @@ -53,8 +53,9 @@ simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt) -expr_stmt: testlist (augassign (yield_expr|testlist) | - ('=' (yield_expr|testlist))*) +expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) +testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter @@ -112,6 +113,7 @@ not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +star_expr: '*' expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* @@ -125,14 +127,14 @@ '{' [dictsetmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ | '.' '.' '.') -listmaker: test ( comp_for | (',' test)* [','] ) -testlist_gexp: test ( comp_for | (',' test)* [','] ) +listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_gexp: test ( comp_for | (',' (test|star_expr))* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] -exprlist: expr (',' expr)* [','] +exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | (test (comp_for | (',' test)* [','])) ) Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_idioms.py Mon Nov 2 19:16:28 2009 @@ -29,7 +29,7 @@ # Local imports from .. import fixer_base -from ..fixer_util import Call, Comma, Name, Node, syms +from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" TYPE = "power< 'type' trailer< '(' x=any ')' > >" @@ -130,5 +130,24 @@ else: raise RuntimeError("should not have reached here") sort_stmt.remove() - if next_stmt: - next_stmt[0].prefix = sort_stmt.prefix + + btwn = sort_stmt.prefix + # Keep any prefix lines between the sort_stmt and the list_call and + # shove them right after the sorted() call. + if "\n" in btwn: + if next_stmt: + # The new prefix should be everything from the sort_stmt's + # prefix up to the last newline, then the old prefix after a new + # line. + prefix_lines = (btwn.rpartition("\n")[0], next_stmt[0].prefix) + next_stmt[0].prefix = "\n".join(prefix_lines) + else: + assert list_call.parent + assert list_call.next_sibling is None + # Put a blank line after list_call and set its prefix. + end_line = BlankLine() + list_call.parent.append_child(end_line) + assert list_call.next_sibling is end_line + # The new prefix should be everything up to the first new line + # of sort_stmt's prefix. + end_line.prefix = btwn.rpartition("\n")[0] Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_map.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_map.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_map.py Mon Nov 2 19:16:28 2009 @@ -49,8 +49,7 @@ > | power< - 'map' - args=trailer< '(' [any] ')' > + 'map' trailer< '(' [arglist=any] ')' > > """ @@ -66,13 +65,22 @@ new.prefix = "" new = Call(Name("list"), [new]) elif "map_lambda" in results: - new = ListComp(results.get("xp").clone(), - results.get("fp").clone(), - results.get("it").clone()) + new = ListComp(results["xp"].clone(), + results["fp"].clone(), + results["it"].clone()) else: if "map_none" in results: new = results["arg"].clone() else: + if "arglist" in results: + args = results["arglist"] + if args.type == syms.arglist and \ + args.children[0].type == token.NAME and \ + args.children[0].value == "None": + self.warning(node, "cannot convert map(None, ...) " + "with multiple arguments because map() " + "now truncates to the shortest sequence") + return if in_special_context(node): return None new = node.clone() Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_tuple_params.py Mon Nov 2 19:16:28 2009 @@ -96,6 +96,8 @@ new_lines[0].prefix = indent after = start + 1 + for line in new_lines: + line.parent = suite[0] suite[0].children[after:after] = new_lines for i in range(after+1, after+len(new_lines)+1): suite[0].children[i].prefix = indent Modified: python/branches/py3k/Lib/lib2to3/pgen2/pgen.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/pgen2/pgen.py (original) +++ python/branches/py3k/Lib/lib2to3/pgen2/pgen.py Mon Nov 2 19:16:28 2009 @@ -379,6 +379,8 @@ return False return True + __hash__ = None # For Py3 compatibility. + def generate_grammar(filename="Grammar.txt"): p = ParserGenerator(filename) return p.make_grammar() Modified: python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py (original) +++ python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py Mon Nov 2 19:16:28 2009 @@ -231,6 +231,17 @@ cookie_re = re.compile("coding[:=]\s*([-\w.]+)") +def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + def detect_encoding(readline): """ The detect_encoding() function is used to detect the encoding that should @@ -265,7 +276,7 @@ matches = cookie_re.findall(line_string) if not matches: return None - encoding = matches[0] + encoding = _get_normal_name(matches[0]) try: codec = lookup(encoding) except LookupError: @@ -375,7 +386,7 @@ column = 0 while pos < max: # measure leading whitespace if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize + elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize elif line[pos] == '\f': column = 0 else: break pos = pos + 1 Modified: python/branches/py3k/Lib/lib2to3/pytree.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/pytree.py (original) +++ python/branches/py3k/Lib/lib2to3/pytree.py Mon Nov 2 19:16:28 2009 @@ -63,6 +63,8 @@ return NotImplemented return self._eq(other) + __hash__ = None # For Py3 compatibility. + def __ne__(self, other): """ Compare two nodes for inequality. Modified: python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py Mon Nov 2 19:16:28 2009 @@ -16,8 +16,7 @@ class Test_all(support.TestCase): def setUp(self): - options = {"print_function" : False} - self.refactor = support.get_refactorer(options=options) + self.refactor = support.get_refactorer() def test_all_project_files(self): for filepath in support.all_project_files(): Modified: python/branches/py3k/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_fixers.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_fixers.py Mon Nov 2 19:16:28 2009 @@ -339,6 +339,12 @@ a = "from functools import reduce\nreduce(a, b, c)" self.check(b, a) + def test_bug_7253(self): + # fix_tuple_params was being bad and orphaning nodes in the tree. + b = "def x(arg): reduce(sum, [])" + a = "from functools import reduce\ndef x(arg): reduce(sum, [])" + self.check(b, a) + def test_call_with_lambda(self): b = "reduce(lambda x, y: x + y, seq)" a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" @@ -2834,6 +2840,11 @@ a = """x = list(map(f, 'abc')) # foo""" self.check(b, a) + def test_None_with_multiple_arguments(self): + s = """x = map(None, a, b, c)""" + self.warns_unchanged(s, "cannot convert map(None, ...) with " + "multiple arguments") + def test_map_basic(self): b = """x = map(f, 'abc')""" a = """x = list(map(f, 'abc'))""" @@ -2847,10 +2858,6 @@ a = """x = list('abc')""" self.check(b, a) - b = """x = map(None, 'abc', 'def')""" - a = """x = list(map(None, 'abc', 'def'))""" - self.check(b, a) - b = """x = map(lambda x: x+1, range(4))""" a = """x = [x+1 for x in range(4)]""" self.check(b, a) @@ -3238,6 +3245,46 @@ """ self.check(b, a) + b = r""" + try: + m = list(s) + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + except: pass + """ + self.check(b, a) + + b = r""" + try: + m = list(s) + # foo + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + # foo + except: pass + """ + self.check(b, a) + + b = r""" + m = list(s) + # more comments + m.sort()""" + + a = r""" + m = sorted(s) + # more comments""" + self.check(b, a) + def test_sort_simple_expr(self): b = """ v = t Modified: python/branches/py3k/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_parser.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_parser.py Mon Nov 2 19:16:28 2009 @@ -161,6 +161,11 @@ if diff(filepath, new): self.fail("Idempotency failed: %s" % filepath) + def test_extended_unpacking(self): + driver.parse_string("a, *b, c = x\n") + driver.parse_string("[*a, b] = x\n") + driver.parse_string("(z, *y, w) = m\n") + driver.parse_string("for *z, m in d: pass\n") class TestLiterals(GrammarTest): From python-checkins at python.org Mon Nov 2 19:16:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:16:36 -0000 Subject: [Python-checkins] r76064 - python/trunk/Lib/test/test_lib2to3.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:16:36 2009 New Revision: 76064 Log: add space Modified: python/trunk/Lib/test/test_lib2to3.py Modified: python/trunk/Lib/test/test_lib2to3.py ============================================================================== --- python/trunk/Lib/test/test_lib2to3.py (original) +++ python/trunk/Lib/test/test_lib2to3.py Mon Nov 2 19:16:36 2009 @@ -7,7 +7,7 @@ def suite(): tests = unittest.TestSuite() loader = unittest.TestLoader() - for m in (test_fixers,test_pytree,test_util, test_refactor): + for m in (test_fixers, test_pytree,test_util, test_refactor): tests.addTests(loader.loadTestsFromModule(m)) return tests From python-checkins at python.org Mon Nov 2 19:21:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:21:25 -0000 Subject: [Python-checkins] r76065 - in sandbox/trunk/2to3/lib2to3/tests: test_all_fixers.py test_parser.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:21:25 2009 New Revision: 76065 Log: don't print stuff in tests Modified: sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py sandbox/trunk/2to3/lib2to3/tests/test_parser.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py Mon Nov 2 19:21:25 2009 @@ -19,5 +19,4 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print "Fixing %s..." % filepath self.refactor.refactor_file(filepath) Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_parser.py Mon Nov 2 19:21:25 2009 @@ -147,7 +147,6 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print "Parsing %s..." % filepath with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] fp.seek(0) From python-checkins at python.org Mon Nov 2 19:22:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:22:54 -0000 Subject: [Python-checkins] r76066 - in python/trunk/Lib/lib2to3: tests/test_all_fixers.py tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:22:53 2009 New Revision: 76066 Log: Merged revisions 76065 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76065 | benjamin.peterson | 2009-11-02 12:21:25 -0600 (Mon, 02 Nov 2009) | 1 line don't print stuff in tests ........ Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/tests/test_all_fixers.py python/trunk/Lib/lib2to3/tests/test_parser.py Modified: python/trunk/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/trunk/Lib/lib2to3/tests/test_all_fixers.py Mon Nov 2 19:22:53 2009 @@ -19,5 +19,4 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print "Fixing %s..." % filepath self.refactor.refactor_file(filepath) Modified: python/trunk/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_parser.py (original) +++ python/trunk/Lib/lib2to3/tests/test_parser.py Mon Nov 2 19:22:53 2009 @@ -147,7 +147,6 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print "Parsing %s..." % filepath with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] fp.seek(0) From python-checkins at python.org Mon Nov 2 19:24:57 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:24:57 -0000 Subject: [Python-checkins] r76067 - python/trunk/Lib/test/test_lib2to3.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:24:57 2009 New Revision: 76067 Log: enable test_parser in lib2to3 Modified: python/trunk/Lib/test/test_lib2to3.py Modified: python/trunk/Lib/test/test_lib2to3.py ============================================================================== --- python/trunk/Lib/test/test_lib2to3.py (original) +++ python/trunk/Lib/test/test_lib2to3.py Mon Nov 2 19:24:57 2009 @@ -1,13 +1,14 @@ # Skipping test_parser and test_all_fixers # because of running -from lib2to3.tests import test_fixers, test_pytree, test_util, test_refactor +from lib2to3.tests import (test_fixers, test_pytree, test_util, test_refactor, + test_parser) import unittest from test.test_support import run_unittest def suite(): tests = unittest.TestSuite() loader = unittest.TestLoader() - for m in (test_fixers, test_pytree,test_util, test_refactor): + for m in (test_fixers, test_pytree,test_util, test_refactor, test_parser): tests.addTests(loader.loadTestsFromModule(m)) return tests From python-checkins at python.org Mon Nov 2 19:30:48 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:30:48 -0000 Subject: [Python-checkins] r76068 - in python/branches/py3k: Lib/lib2to3/tests/test_all_fixers.py Lib/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:30:48 2009 New Revision: 76068 Log: Merged revisions 76064,76066-76067 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76064 | benjamin.peterson | 2009-11-02 12:16:36 -0600 (Mon, 02 Nov 2009) | 1 line add space ................ r76066 | benjamin.peterson | 2009-11-02 12:22:53 -0600 (Mon, 02 Nov 2009) | 9 lines Merged revisions 76065 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76065 | benjamin.peterson | 2009-11-02 12:21:25 -0600 (Mon, 02 Nov 2009) | 1 line don't print stuff in tests ........ ................ r76067 | benjamin.peterson | 2009-11-02 12:24:57 -0600 (Mon, 02 Nov 2009) | 1 line enable test_parser in lib2to3 ................ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py python/branches/py3k/Lib/lib2to3/tests/test_parser.py Modified: python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_all_fixers.py Mon Nov 2 19:30:48 2009 @@ -20,5 +20,4 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print("Fixing %s..." % filepath) self.refactor.refactor_file(filepath) Modified: python/branches/py3k/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_parser.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_parser.py Mon Nov 2 19:30:48 2009 @@ -147,7 +147,6 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print("Parsing %s..." % filepath) with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] fp.seek(0) From python-checkins at python.org Mon Nov 2 19:33:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 18:33:36 -0000 Subject: [Python-checkins] r76069 - in python/branches/release31-maint: Lib/lib2to3/Grammar.txt Lib/lib2to3/fixes/fix_idioms.py Lib/lib2to3/fixes/fix_map.py Lib/lib2to3/fixes/fix_tuple_params.py Lib/lib2to3/pgen2/pgen.py Lib/lib2to3/pgen2/tokenize.py Lib/lib2to3/pytree.py Lib/lib2to3/tests/test_all_fixers.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Mon Nov 2 19:33:36 2009 New Revision: 76069 Log: Merged revisions 76063,76068 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76063 | benjamin.peterson | 2009-11-02 12:16:28 -0600 (Mon, 02 Nov 2009) | 77 lines Merged revisions 76062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76062 | benjamin.peterson | 2009-11-02 12:12:12 -0600 (Mon, 02 Nov 2009) | 70 lines Merged revisions 74359,75081,75088,75213,75278,75303,75427-75428,75734-75736,75865,76059-76061 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r74359 | benjamin.peterson | 2009-08-12 17:23:13 -0500 (Wed, 12 Aug 2009) | 1 line don't pass the deprecated print_function option ........ r75081 | benjamin.peterson | 2009-09-26 22:02:57 -0500 (Sat, 26 Sep 2009) | 1 line let 2to3 work with extended iterable unpacking ........ r75088 | benjamin.peterson | 2009-09-27 11:25:21 -0500 (Sun, 27 Sep 2009) | 1 line look on the type only for __call__ ........ r75213 | benjamin.peterson | 2009-10-03 10:09:46 -0500 (Sat, 03 Oct 2009) | 5 lines revert 75212; it's not correct People can use isinstance(x, collections.Callable) if they expect objects with __call__ in their instance dictionaries. ........ r75278 | benjamin.peterson | 2009-10-07 16:25:56 -0500 (Wed, 07 Oct 2009) | 4 lines fix whitespace problems with fix_idioms #3563 Patch by Joe Amenta. ........ r75303 | benjamin.peterson | 2009-10-09 16:59:11 -0500 (Fri, 09 Oct 2009) | 1 line port latin-1 and utf-8 cookie improvements ........ r75427 | benjamin.peterson | 2009-10-14 20:35:57 -0500 (Wed, 14 Oct 2009) | 1 line force floor division ........ r75428 | benjamin.peterson | 2009-10-14 20:39:21 -0500 (Wed, 14 Oct 2009) | 1 line silence -3 warnings about __hash__ ........ r75734 | benjamin.peterson | 2009-10-26 16:25:53 -0500 (Mon, 26 Oct 2009) | 2 lines warn on map(None, ...) with more than 2 arguments #7203 ........ r75735 | benjamin.peterson | 2009-10-26 16:28:25 -0500 (Mon, 26 Oct 2009) | 1 line remove unused result ........ r75736 | benjamin.peterson | 2009-10-26 16:29:02 -0500 (Mon, 26 Oct 2009) | 1 line using get() here is a bit pointless ........ r75865 | benjamin.peterson | 2009-10-27 15:49:00 -0500 (Tue, 27 Oct 2009) | 1 line explain reason for warning ........ r76059 | benjamin.peterson | 2009-11-02 11:43:47 -0600 (Mon, 02 Nov 2009) | 1 line tuples are no longer used for children ........ r76060 | benjamin.peterson | 2009-11-02 11:55:40 -0600 (Mon, 02 Nov 2009) | 1 line revert r76059; apparently some fixers rely on Leaf no () for children ........ r76061 | benjamin.peterson | 2009-11-02 12:06:17 -0600 (Mon, 02 Nov 2009) | 1 line make fix_tuple_params keep the tree valid #7253 ........ ................ ................ r76068 | benjamin.peterson | 2009-11-02 12:30:48 -0600 (Mon, 02 Nov 2009) | 24 lines Merged revisions 76064,76066-76067 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76064 | benjamin.peterson | 2009-11-02 12:16:36 -0600 (Mon, 02 Nov 2009) | 1 line add space ................ r76066 | benjamin.peterson | 2009-11-02 12:22:53 -0600 (Mon, 02 Nov 2009) | 9 lines Merged revisions 76065 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76065 | benjamin.peterson | 2009-11-02 12:21:25 -0600 (Mon, 02 Nov 2009) | 1 line don't print stuff in tests ........ ................ r76067 | benjamin.peterson | 2009-11-02 12:24:57 -0600 (Mon, 02 Nov 2009) | 1 line enable test_parser in lib2to3 ................ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/lib2to3/Grammar.txt python/branches/release31-maint/Lib/lib2to3/fixes/fix_idioms.py python/branches/release31-maint/Lib/lib2to3/fixes/fix_map.py python/branches/release31-maint/Lib/lib2to3/fixes/fix_tuple_params.py python/branches/release31-maint/Lib/lib2to3/pgen2/pgen.py python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py python/branches/release31-maint/Lib/lib2to3/pytree.py python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py python/branches/release31-maint/Lib/lib2to3/tests/test_parser.py Modified: python/branches/release31-maint/Lib/lib2to3/Grammar.txt ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/Grammar.txt (original) +++ python/branches/release31-maint/Lib/lib2to3/Grammar.txt Mon Nov 2 19:33:36 2009 @@ -53,8 +53,9 @@ simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt) -expr_stmt: testlist (augassign (yield_expr|testlist) | - ('=' (yield_expr|testlist))*) +expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) +testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter @@ -112,6 +113,7 @@ not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +star_expr: '*' expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* @@ -125,14 +127,14 @@ '{' [dictsetmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ | '.' '.' '.') -listmaker: test ( comp_for | (',' test)* [','] ) -testlist_gexp: test ( comp_for | (',' test)* [','] ) +listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_gexp: test ( comp_for | (',' (test|star_expr))* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] -exprlist: expr (',' expr)* [','] +exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | (test (comp_for | (',' test)* [','])) ) Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_idioms.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_idioms.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_idioms.py Mon Nov 2 19:33:36 2009 @@ -29,7 +29,7 @@ # Local imports from .. import fixer_base -from ..fixer_util import Call, Comma, Name, Node, syms +from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" TYPE = "power< 'type' trailer< '(' x=any ')' > >" @@ -130,5 +130,24 @@ else: raise RuntimeError("should not have reached here") sort_stmt.remove() - if next_stmt: - next_stmt[0].prefix = sort_stmt.prefix + + btwn = sort_stmt.prefix + # Keep any prefix lines between the sort_stmt and the list_call and + # shove them right after the sorted() call. + if "\n" in btwn: + if next_stmt: + # The new prefix should be everything from the sort_stmt's + # prefix up to the last newline, then the old prefix after a new + # line. + prefix_lines = (btwn.rpartition("\n")[0], next_stmt[0].prefix) + next_stmt[0].prefix = "\n".join(prefix_lines) + else: + assert list_call.parent + assert list_call.next_sibling is None + # Put a blank line after list_call and set its prefix. + end_line = BlankLine() + list_call.parent.append_child(end_line) + assert list_call.next_sibling is end_line + # The new prefix should be everything up to the first new line + # of sort_stmt's prefix. + end_line.prefix = btwn.rpartition("\n")[0] Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_map.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_map.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_map.py Mon Nov 2 19:33:36 2009 @@ -49,8 +49,7 @@ > | power< - 'map' - args=trailer< '(' [any] ')' > + 'map' trailer< '(' [arglist=any] ')' > > """ @@ -66,13 +65,22 @@ new.prefix = "" new = Call(Name("list"), [new]) elif "map_lambda" in results: - new = ListComp(results.get("xp").clone(), - results.get("fp").clone(), - results.get("it").clone()) + new = ListComp(results["xp"].clone(), + results["fp"].clone(), + results["it"].clone()) else: if "map_none" in results: new = results["arg"].clone() else: + if "arglist" in results: + args = results["arglist"] + if args.type == syms.arglist and \ + args.children[0].type == token.NAME and \ + args.children[0].value == "None": + self.warning(node, "cannot convert map(None, ...) " + "with multiple arguments because map() " + "now truncates to the shortest sequence") + return if in_special_context(node): return None new = node.clone() Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_tuple_params.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_tuple_params.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_tuple_params.py Mon Nov 2 19:33:36 2009 @@ -96,6 +96,8 @@ new_lines[0].prefix = indent after = start + 1 + for line in new_lines: + line.parent = suite[0] suite[0].children[after:after] = new_lines for i in range(after+1, after+len(new_lines)+1): suite[0].children[i].prefix = indent Modified: python/branches/release31-maint/Lib/lib2to3/pgen2/pgen.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/pgen2/pgen.py (original) +++ python/branches/release31-maint/Lib/lib2to3/pgen2/pgen.py Mon Nov 2 19:33:36 2009 @@ -379,6 +379,8 @@ return False return True + __hash__ = None # For Py3 compatibility. + def generate_grammar(filename="Grammar.txt"): p = ParserGenerator(filename) return p.make_grammar() Modified: python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py (original) +++ python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py Mon Nov 2 19:33:36 2009 @@ -231,6 +231,17 @@ cookie_re = re.compile("coding[:=]\s*([-\w.]+)") +def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + def detect_encoding(readline): """ The detect_encoding() function is used to detect the encoding that should @@ -265,7 +276,7 @@ matches = cookie_re.findall(line_string) if not matches: return None - encoding = matches[0] + encoding = _get_normal_name(matches[0]) try: codec = lookup(encoding) except LookupError: @@ -375,7 +386,7 @@ column = 0 while pos < max: # measure leading whitespace if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize + elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize elif line[pos] == '\f': column = 0 else: break pos = pos + 1 Modified: python/branches/release31-maint/Lib/lib2to3/pytree.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/pytree.py (original) +++ python/branches/release31-maint/Lib/lib2to3/pytree.py Mon Nov 2 19:33:36 2009 @@ -63,6 +63,8 @@ return NotImplemented return self._eq(other) + __hash__ = None # For Py3 compatibility. + def __ne__(self, other): """ Compare two nodes for inequality. Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_all_fixers.py Mon Nov 2 19:33:36 2009 @@ -16,10 +16,8 @@ class Test_all(support.TestCase): def setUp(self): - options = {"print_function" : False} - self.refactor = support.get_refactorer(options=options) + self.refactor = support.get_refactorer() def test_all_project_files(self): for filepath in support.all_project_files(): - print("Fixing %s..." % filepath) self.refactor.refactor_file(filepath) Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py Mon Nov 2 19:33:36 2009 @@ -339,6 +339,12 @@ a = "from functools import reduce\nreduce(a, b, c)" self.check(b, a) + def test_bug_7253(self): + # fix_tuple_params was being bad and orphaning nodes in the tree. + b = "def x(arg): reduce(sum, [])" + a = "from functools import reduce\ndef x(arg): reduce(sum, [])" + self.check(b, a) + def test_call_with_lambda(self): b = "reduce(lambda x, y: x + y, seq)" a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" @@ -2834,6 +2840,11 @@ a = """x = list(map(f, 'abc')) # foo""" self.check(b, a) + def test_None_with_multiple_arguments(self): + s = """x = map(None, a, b, c)""" + self.warns_unchanged(s, "cannot convert map(None, ...) with " + "multiple arguments") + def test_map_basic(self): b = """x = map(f, 'abc')""" a = """x = list(map(f, 'abc'))""" @@ -2847,10 +2858,6 @@ a = """x = list('abc')""" self.check(b, a) - b = """x = map(None, 'abc', 'def')""" - a = """x = list(map(None, 'abc', 'def'))""" - self.check(b, a) - b = """x = map(lambda x: x+1, range(4))""" a = """x = [x+1 for x in range(4)]""" self.check(b, a) @@ -3238,6 +3245,46 @@ """ self.check(b, a) + b = r""" + try: + m = list(s) + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + except: pass + """ + self.check(b, a) + + b = r""" + try: + m = list(s) + # foo + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + # foo + except: pass + """ + self.check(b, a) + + b = r""" + m = list(s) + # more comments + m.sort()""" + + a = r""" + m = sorted(s) + # more comments""" + self.check(b, a) + def test_sort_simple_expr(self): b = """ v = t Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_parser.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_parser.py Mon Nov 2 19:33:36 2009 @@ -147,7 +147,6 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print("Parsing %s..." % filepath) with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] fp.seek(0) @@ -161,6 +160,11 @@ if diff(filepath, new): self.fail("Idempotency failed: %s" % filepath) + def test_extended_unpacking(self): + driver.parse_string("a, *b, c = x\n") + driver.parse_string("[*a, b] = x\n") + driver.parse_string("(z, *y, w) = m\n") + driver.parse_string("for *z, m in d: pass\n") class TestLiterals(GrammarTest): From python-checkins at python.org Mon Nov 2 20:59:07 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 02 Nov 2009 19:59:07 -0000 Subject: [Python-checkins] r76070 - peps/trunk/pep-0373.txt Message-ID: Author: benjamin.peterson Date: Mon Nov 2 20:59:07 2009 New Revision: 76070 Log: finally! a concrete schedule Modified: peps/trunk/pep-0373.txt Modified: peps/trunk/pep-0373.txt ============================================================================== --- peps/trunk/pep-0373.txt (original) +++ peps/trunk/pep-0373.txt Mon Nov 2 20:59:07 2009 @@ -1,5 +1,5 @@ PEP: 373 -Title: Python 2.7 Release Schedule +Title: Python 2.7 and 3.2 Release Schedule Version: $Revision$ Last-Modified: $Date$ Author: Benjamin Peterson @@ -7,7 +7,7 @@ Type: Informational Content-Type: text/x-rst Created: 3-Nov-2008 -Python-Version: 2.7 +Python-Version: 2.7, 3.2 Abstract @@ -22,25 +22,39 @@ Release Manager and Crew ======================== -=================== ================== -Position Name -=================== ================== -2.7 Release Manager Benjamin Peterson -Windows installers Martin v. Loewis -Mac installers Ronald Oussoren -=================== ================== +============================ ================== +Position Name +============================ ================== +2.7 and 3.2 Release Manager Benjamin Peterson +Windows installers Martin v. Loewis +Mac installers Ronald Oussoren +============================ ================== Release Schedule ================ -Not yet finalized. +2.7 and 3.2 will be released at the same time (or at least have feature freeze +at the same time) in order to keep the 2.x branch from having features that the +3.x one does not. + +The current schedule is: + +- 2.7/3.2 alpha 1 2009-12-05 +- 2.7/3.2 alpha 2 2010-01-09 +- 2.7/3.2 alpha 3 2010-02-06 +- 2.7/3.2 alpha 4 2010-03-06 +- 2.7/3.2 beta 1 2010-04-03 +- 2.7/3.2 beta 2 2010-05-01 +- 2.7/3.2 rc1 2010-05-29 +- 2.7/3.2 rc2 2010-06-12 +- 2.7/3.2 final 2010-06-26 Possible features for 2.7 ========================= -Nothing here. +Nothing here. [Note that a moratorium on core language changes in is in effect.] References From python-checkins at python.org Mon Nov 2 21:47:33 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 20:47:33 -0000 Subject: [Python-checkins] r76071 - python/trunk/Lib/test/test_memoryio.py Message-ID: Author: antoine.pitrou Date: Mon Nov 2 21:47:33 2009 New Revision: 76071 Log: Add acceptance of long ints to test_memoryio.py (in preparation for fix of #7249 in 2.6) Modified: python/trunk/Lib/test/test_memoryio.py Modified: python/trunk/Lib/test/test_memoryio.py ============================================================================== --- python/trunk/Lib/test/test_memoryio.py (original) +++ python/trunk/Lib/test/test_memoryio.py Mon Nov 2 21:47:33 2009 @@ -124,6 +124,9 @@ self.assertEqual(memio.getvalue(), buf[:6]) self.assertEqual(memio.truncate(4), 4) self.assertEqual(memio.getvalue(), buf[:4]) + # truncate() accepts long objects + self.assertEqual(memio.truncate(4L), 4) + self.assertEqual(memio.getvalue(), buf[:4]) self.assertEqual(memio.tell(), 4) memio.write(buf) self.assertEqual(memio.getvalue(), buf[:4] + buf) @@ -153,7 +156,8 @@ self.assertEqual(memio.read(0), self.EOF) self.assertEqual(memio.read(1), buf[:1]) - self.assertEqual(memio.read(4), buf[1:5]) + # read() accepts long objects + self.assertEqual(memio.read(4L), buf[1:5]) self.assertEqual(memio.read(900), buf[5:]) self.assertEqual(memio.read(), self.EOF) memio.seek(0) @@ -184,7 +188,8 @@ self.assertEqual(memio.readline(), self.EOF) memio.seek(0) self.assertEqual(memio.readline(5), buf[:5]) - self.assertEqual(memio.readline(5), buf[5:10]) + # readline() accepts long objects + self.assertEqual(memio.readline(5L), buf[5:10]) self.assertEqual(memio.readline(5), buf[10:15]) memio.seek(0) self.assertEqual(memio.readline(-1), buf) @@ -212,7 +217,8 @@ memio.seek(5) self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9) memio.seek(0) - self.assertEqual(memio.readlines(15), [buf] * 2) + # readlines() accepts long objects + self.assertEqual(memio.readlines(15L), [buf] * 2) memio.seek(0) self.assertEqual(memio.readlines(-1), [buf] * 10) memio.seek(0) @@ -273,6 +279,8 @@ self.assertEqual(memio.seek(0, 0), 0) self.assertEqual(memio.read(), buf) self.assertEqual(memio.seek(3), 3) + # seek() accepts long objects + self.assertEqual(memio.seek(3L), 3) self.assertEqual(memio.seek(0, 1), 3) self.assertEqual(memio.read(), buf[3:]) self.assertEqual(memio.seek(len(buf)), len(buf)) From python-checkins at python.org Mon Nov 2 21:57:43 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 20:57:43 -0000 Subject: [Python-checkins] r76072 - python/branches/py3k Message-ID: Author: antoine.pitrou Date: Mon Nov 2 21:57:43 2009 New Revision: 76072 Log: Blocked revisions 76071 via svnmerge ........ r76071 | antoine.pitrou | 2009-11-02 21:47:33 +0100 (lun., 02 nov. 2009) | 4 lines Add acceptance of long ints to test_memoryio.py (in preparation for fix of #7249 in 2.6) ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Nov 2 22:03:54 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 21:03:54 -0000 Subject: [Python-checkins] r76073 - in python/branches/release26-maint: Lib/test/test_memoryio.py Misc/NEWS Modules/_bytesio.c Message-ID: Author: antoine.pitrou Date: Mon Nov 2 22:03:53 2009 New Revision: 76073 Log: Issue #7249: Methods of io.BytesIO now allow `long` as well as `int` arguments. Merged revisions 76071 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76071 | antoine.pitrou | 2009-11-02 21:47:33 +0100 (lun., 02 nov. 2009) | 4 lines Add acceptance of long ints to test_memoryio.py (in preparation for fix of #7249 in 2.6) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_memoryio.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_bytesio.c Modified: python/branches/release26-maint/Lib/test/test_memoryio.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_memoryio.py (original) +++ python/branches/release26-maint/Lib/test/test_memoryio.py Mon Nov 2 22:03:53 2009 @@ -80,6 +80,9 @@ self.assertEqual(memio.getvalue(), buf[:6]) self.assertEqual(memio.truncate(4), 4) self.assertEqual(memio.getvalue(), buf[:4]) + # truncate() accepts long objects + self.assertEqual(memio.truncate(4L), 4) + self.assertEqual(memio.getvalue(), buf[:4]) self.assertEqual(memio.tell(), 4) memio.write(buf) self.assertEqual(memio.getvalue(), buf[:4] + buf) @@ -107,7 +110,8 @@ self.assertEqual(memio.read(0), self.EOF) self.assertEqual(memio.read(1), buf[:1]) - self.assertEqual(memio.read(4), buf[1:5]) + # read() accepts long objects + self.assertEqual(memio.read(4L), buf[1:5]) self.assertEqual(memio.read(900), buf[5:]) self.assertEqual(memio.read(), self.EOF) memio.seek(0) @@ -136,7 +140,8 @@ self.assertEqual(memio.readline(), self.EOF) memio.seek(0) self.assertEqual(memio.readline(5), buf[:5]) - self.assertEqual(memio.readline(5), buf[5:10]) + # readline() accepts long objects + self.assertEqual(memio.readline(5L), buf[5:10]) self.assertEqual(memio.readline(5), buf[10:15]) memio.seek(0) self.assertEqual(memio.readline(-1), buf) @@ -164,7 +169,8 @@ memio.seek(5) self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9) memio.seek(0) - self.assertEqual(memio.readlines(15), [buf] * 2) + # readlines() accepts long objects + self.assertEqual(memio.readlines(15L), [buf] * 2) memio.seek(0) self.assertEqual(memio.readlines(-1), [buf] * 10) memio.seek(0) @@ -225,6 +231,8 @@ self.assertEqual(memio.seek(0, 0), 0) self.assertEqual(memio.read(), buf) self.assertEqual(memio.seek(3), 3) + # seek() accepts long objects + self.assertEqual(memio.seek(3L), 3) self.assertEqual(memio.seek(0, 1), 3) self.assertEqual(memio.read(), buf[3:]) self.assertEqual(memio.seek(len(buf)), len(buf)) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Nov 2 22:03:53 2009 @@ -24,6 +24,9 @@ Library ------- +- Issue #7249: Methods of io.BytesIO now allow `long` as well as `int` + arguments. + - Issue #6665: Fix fnmatch to properly match filenames with newlines in them. - Issue #1008086: Fixed socket.inet_aton() to always return 4 bytes even on Modified: python/branches/release26-maint/Modules/_bytesio.c ============================================================================== --- python/branches/release26-maint/Modules/_bytesio.c (original) +++ python/branches/release26-maint/Modules/_bytesio.c Mon Nov 2 22:03:53 2009 @@ -219,8 +219,8 @@ if (!PyArg_ParseTuple(args, "|O:read", &arg)) return NULL; - if (PyInt_Check(arg)) { - size = PyInt_AsSsize_t(arg); + if (PyIndex_Check(arg)) { + size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) return NULL; } @@ -288,8 +288,8 @@ if (!PyArg_ParseTuple(args, "|O:readline", &arg)) return NULL; - if (PyInt_Check(arg)) { - size = PyInt_AsSsize_t(arg); + if (PyIndex_Check(arg)) { + size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) return NULL; } @@ -334,8 +334,8 @@ if (!PyArg_ParseTuple(args, "|O:readlines", &arg)) return NULL; - if (PyInt_Check(arg)) { - maxsize = PyInt_AsSsize_t(arg); + if (PyIndex_Check(arg)) { + maxsize = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (maxsize == -1 && PyErr_Occurred()) return NULL; } @@ -419,8 +419,8 @@ if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) return NULL; - if (PyInt_Check(arg)) { - size = PyInt_AsSsize_t(arg); + if (PyIndex_Check(arg)) { + size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (size == -1 && PyErr_Occurred()) return NULL; } From python-checkins at python.org Mon Nov 2 23:04:55 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 02 Nov 2009 22:04:55 -0000 Subject: [Python-checkins] r76074 - python/branches/release26-maint/Lib/test/test_httpservers.py Message-ID: Author: antoine.pitrou Date: Mon Nov 2 23:04:54 2009 New Revision: 76074 Log: Try to fix test_wsgiref failures due to test_httpservers modifying the environment Modified: python/branches/release26-maint/Lib/test/test_httpservers.py Modified: python/branches/release26-maint/Lib/test/test_httpservers.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_httpservers.py (original) +++ python/branches/release26-maint/Lib/test/test_httpservers.py Mon Nov 2 23:04:54 2009 @@ -341,13 +341,17 @@ def test_main(verbose=None): + cwd = os.getcwd() + env = os.environ.copy() try: - cwd = os.getcwd() test_support.run_unittest(BaseHTTPServerTestCase, SimpleHTTPServerTestCase, CGIHTTPServerTestCase ) finally: + test_support.reap_children() + os.environ.clear() + os.environ.update(env) os.chdir(cwd) if __name__ == '__main__': From python-checkins at python.org Tue Nov 3 03:43:59 2009 From: python-checkins at python.org (skip.montanaro) Date: Tue, 03 Nov 2009 02:43:59 -0000 Subject: [Python-checkins] r76075 - python/trunk/Doc/library/datetime.rst Message-ID: Author: skip.montanaro Date: Tue Nov 3 03:43:59 2009 New Revision: 76075 Log: typo (space-o?) Modified: python/trunk/Doc/library/datetime.rst Modified: python/trunk/Doc/library/datetime.rst ============================================================================== --- python/trunk/Doc/library/datetime.rst (original) +++ python/trunk/Doc/library/datetime.rst Tue Nov 3 03:43:59 2009 @@ -471,7 +471,7 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/ vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From python-checkins at python.org Tue Nov 3 03:44:04 2009 From: python-checkins at python.org (skip.montanaro) Date: Tue, 03 Nov 2009 02:44:04 -0000 Subject: [Python-checkins] r76076 - python/branches/py3k/Doc/library/datetime.rst Message-ID: Author: skip.montanaro Date: Tue Nov 3 03:44:04 2009 New Revision: 76076 Log: typo (space-o?) Modified: python/branches/py3k/Doc/library/datetime.rst Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Tue Nov 3 03:44:04 2009 @@ -469,7 +469,7 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/ vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From python-checkins at python.org Tue Nov 3 03:44:50 2009 From: python-checkins at python.org (skip.montanaro) Date: Tue, 03 Nov 2009 02:44:50 -0000 Subject: [Python-checkins] r76077 - python/branches/release26-maint/Doc/library/datetime.rst Message-ID: Author: skip.montanaro Date: Tue Nov 3 03:44:50 2009 New Revision: 76077 Log: typo (space-o?) Modified: python/branches/release26-maint/Doc/library/datetime.rst Modified: python/branches/release26-maint/Doc/library/datetime.rst ============================================================================== --- python/branches/release26-maint/Doc/library/datetime.rst (original) +++ python/branches/release26-maint/Doc/library/datetime.rst Tue Nov 3 03:44:50 2009 @@ -471,7 +471,7 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/ vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From python-checkins at python.org Tue Nov 3 03:44:54 2009 From: python-checkins at python.org (skip.montanaro) Date: Tue, 03 Nov 2009 02:44:54 -0000 Subject: [Python-checkins] r76078 - python/branches/release31-maint/Doc/library/datetime.rst Message-ID: Author: skip.montanaro Date: Tue Nov 3 03:44:54 2009 New Revision: 76078 Log: typo (space-o?) Modified: python/branches/release31-maint/Doc/library/datetime.rst Modified: python/branches/release31-maint/Doc/library/datetime.rst ============================================================================== --- python/branches/release31-maint/Doc/library/datetime.rst (original) +++ python/branches/release31-maint/Doc/library/datetime.rst Tue Nov 3 03:44:54 2009 @@ -469,7 +469,7 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/ vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From nnorwitz at gmail.com Tue Nov 3 04:57:18 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 2 Nov 2009 20:57:18 -0700 Subject: [Python-checkins] Python Regression Test Failures refleak (2) In-Reply-To: References: <20091102000404.GA21764@kbk-i386-bb.psfb.org> Message-ID: On Sun, Nov 1, 2009 at 5:59 PM, Antoine Pitrou wrote: > > Neal Norwitz gmail.com> writes: >> > [snip refleak results] > > Neal, for what branch and what revision are those results? You can find all the answers here: http://docs.python.org/dev/results/ The script that generates these results is: Misc/build.sh The output from running with leak detection: http://docs.python.org/dev/results/make-test-refleak.out Last run was at r76072 on trunk. HTH, n From brett at python.org Tue Nov 3 05:07:05 2009 From: brett at python.org (Brett Cannon) Date: Mon, 2 Nov 2009 20:07:05 -0800 Subject: [Python-checkins] r76070 - peps/trunk/pep-0373.txt In-Reply-To: <4aef3a17.1767f10a.2303.ffff9aa8SMTPIN_ADDED@mx.google.com> References: <4aef3a17.1767f10a.2303.ffff9aa8SMTPIN_ADDED@mx.google.com> Message-ID: On Mon, Nov 2, 2009 at 11:59, benjamin.peterson wrote: [SNIP] > ?Possible features for 2.7 > ?========================= > > -Nothing here. > +Nothing here. [Note that a moratorium on core language changes in is in effect.] There's an extra "in". From python-checkins at python.org Tue Nov 3 05:10:37 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 03 Nov 2009 04:10:37 -0000 Subject: [Python-checkins] r76079 - peps/trunk/pep-0373.txt Message-ID: Author: benjamin.peterson Date: Tue Nov 3 05:10:37 2009 New Revision: 76079 Log: remove extra word Modified: peps/trunk/pep-0373.txt Modified: peps/trunk/pep-0373.txt ============================================================================== --- peps/trunk/pep-0373.txt (original) +++ peps/trunk/pep-0373.txt Tue Nov 3 05:10:37 2009 @@ -54,7 +54,7 @@ Possible features for 2.7 ========================= -Nothing here. [Note that a moratorium on core language changes in is in effect.] +Nothing here. [Note that a moratorium on core language changes is in effect.] References From g.brandl at gmx.net Tue Nov 3 08:50:39 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Tue, 03 Nov 2009 08:50:39 +0100 Subject: [Python-checkins] r76070 - peps/trunk/pep-0373.txt In-Reply-To: <35015.934930607$1257191965@news.gmane.org> References: <35015.934930607$1257191965@news.gmane.org> Message-ID: benjamin.peterson schrieb: > Possible features for 2.7 > ========================= > > -Nothing here. > +Nothing here. [Note that a moratorium on core language changes in is in effect.] Time machine? Georg From solipsis at pitrou.net Tue Nov 3 13:42:57 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Tue, 3 Nov 2009 12:42:57 +0000 (UTC) Subject: [Python-checkins] Python Regression Test Failures refleak (2) References: <20091102000404.GA21764@kbk-i386-bb.psfb.org> Message-ID: Neal Norwitz gmail.com> writes: > > You can find all the answers here: http://docs.python.org/dev/results/ > The script that generates these results is: Misc/build.sh Perhaps you could include this info in the automatically generated e-mail? The reason I was asking is that the test_threading leaks aren't reproduceable here. I thought you had an old version of the tree. Thanks Antoine. From python-checkins at python.org Tue Nov 3 15:28:03 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 03 Nov 2009 14:28:03 -0000 Subject: [Python-checkins] r76080 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Tue Nov 3 15:28:03 2009 New Revision: 76080 Log: Unblocked revisions 75518 via svnmerge ........ r75518 | r.david.murray | 2009-10-19 12:01:28 -0400 (Mon, 19 Oct 2009) | 3 lines Only run test_curses when sys.__stdout__ is a tty. This eliminates the last false positive when running regrtest with -j. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Nov 3 15:31:54 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 03 Nov 2009 14:31:54 -0000 Subject: [Python-checkins] r76081 - in python/branches/release26-maint: Lib/test/test_curses.py Message-ID: Author: r.david.murray Date: Tue Nov 3 15:31:53 2009 New Revision: 76081 Log: It turns out test_curses can fail in a 2.6 buildbot because stdout is not a tty in certain cases. Merged revisions 75518 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75518 | r.david.murray | 2009-10-19 12:01:28 -0400 (Mon, 19 Oct 2009) | 3 lines Only run test_curses when sys.__stdout__ is a tty. This eliminates the last false positive when running regrtest with -j. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_curses.py Modified: python/branches/release26-maint/Lib/test/test_curses.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_curses.py (original) +++ python/branches/release26-maint/Lib/test/test_curses.py Tue Nov 3 15:31:53 2009 @@ -269,6 +269,8 @@ curses.wrapper(main) unit_tests() else: + if not sys.__stdout__.isatty(): + raise unittest.SkipTest("sys.__stdout__ is not a tty") # testing setupterm() inside initscr/endwin # causes terminal breakage curses.setupterm(fd=sys.__stdout__.fileno()) From python-checkins at python.org Tue Nov 3 17:26:14 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 03 Nov 2009 16:26:14 -0000 Subject: [Python-checkins] r76082 - python/trunk/Doc/library/datetime.rst Message-ID: Author: mark.dickinson Date: Tue Nov 3 17:26:14 2009 New Revision: 76082 Log: Fix doc typo reported by Arfrever. Modified: python/trunk/Doc/library/datetime.rst Modified: python/trunk/Doc/library/datetime.rst ============================================================================== --- python/trunk/Doc/library/datetime.rst (original) +++ python/trunk/Doc/library/datetime.rst Tue Nov 3 17:26:14 2009 @@ -471,7 +471,8 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From python-checkins at python.org Tue Nov 3 17:27:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 03 Nov 2009 16:27:23 -0000 Subject: [Python-checkins] r76083 - in python/branches/release26-maint: Doc/library/datetime.rst Message-ID: Author: mark.dickinson Date: Tue Nov 3 17:27:23 2009 New Revision: 76083 Log: Merged revisions 76082 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76082 | mark.dickinson | 2009-11-03 16:26:14 +0000 (Tue, 03 Nov 2009) | 1 line Fix doc typo reported by Arfrever. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/datetime.rst Modified: python/branches/release26-maint/Doc/library/datetime.rst ============================================================================== --- python/branches/release26-maint/Doc/library/datetime.rst (original) +++ python/branches/release26-maint/Doc/library/datetime.rst Tue Nov 3 17:27:23 2009 @@ -471,7 +471,8 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From python-checkins at python.org Tue Nov 3 17:29:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 03 Nov 2009 16:29:10 -0000 Subject: [Python-checkins] r76084 - in python/branches/py3k: Doc/library/datetime.rst Message-ID: Author: mark.dickinson Date: Tue Nov 3 17:29:10 2009 New Revision: 76084 Log: Merged revisions 76082 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76082 | mark.dickinson | 2009-11-03 16:26:14 +0000 (Tue, 03 Nov 2009) | 1 line Fix doc typo reported by Arfrever. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/datetime.rst Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Tue Nov 3 17:29:10 2009 @@ -469,7 +469,8 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From python-checkins at python.org Tue Nov 3 17:29:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 03 Nov 2009 16:29:44 -0000 Subject: [Python-checkins] r76085 - in python/branches/release31-maint: Doc/library/datetime.rst Message-ID: Author: mark.dickinson Date: Tue Nov 3 17:29:43 2009 New Revision: 76085 Log: Merged revisions 76084 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76084 | mark.dickinson | 2009-11-03 16:29:10 +0000 (Tue, 03 Nov 2009) | 9 lines Merged revisions 76082 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76082 | mark.dickinson | 2009-11-03 16:26:14 +0000 (Tue, 03 Nov 2009) | 1 line Fix doc typo reported by Arfrever. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/datetime.rst Modified: python/branches/release31-maint/Doc/library/datetime.rst ============================================================================== --- python/branches/release31-maint/Doc/library/datetime.rst (original) +++ python/branches/release31-maint/Doc/library/datetime.rst Tue Nov 3 17:29:43 2009 @@ -469,7 +469,8 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first From benjamin at python.org Tue Nov 3 17:28:31 2009 From: benjamin at python.org (Benjamin Peterson) Date: Tue, 3 Nov 2009 10:28:31 -0600 Subject: [Python-checkins] r76070 - peps/trunk/pep-0373.txt In-Reply-To: References: <35015.934930607$1257191965@news.gmane.org> Message-ID: <1afaf6160911030828m536379acwe6e03ccddea0e27e@mail.gmail.com> 2009/11/3 Georg Brandl : > benjamin.peterson schrieb: > >> ?Possible features for 2.7 >> ?========================= >> >> -Nothing here. >> +Nothing here. [Note that a moratorium on core language changes in is in effect.] > > Time machine? No, just assuming the best until proven wrong. :) -- Regards, Benjamin From python-checkins at python.org Tue Nov 3 17:41:20 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 03 Nov 2009 16:41:20 -0000 Subject: [Python-checkins] r76086 - python/trunk/Lib/test/test_wsgiref.py Message-ID: Author: antoine.pitrou Date: Tue Nov 3 17:41:20 2009 New Revision: 76086 Log: Try to make test_wsgiref less fragile against environment changes by other tests Modified: python/trunk/Lib/test/test_wsgiref.py Modified: python/trunk/Lib/test/test_wsgiref.py ============================================================================== --- python/trunk/Lib/test/test_wsgiref.py (original) +++ python/trunk/Lib/test/test_wsgiref.py Tue Nov 3 17:41:20 2009 @@ -9,7 +9,9 @@ from wsgiref.simple_server import make_server from StringIO import StringIO from SocketServer import BaseServer -import re, sys +import os +import re +import sys from test import test_support @@ -386,6 +388,11 @@ class ErrorHandler(BaseCGIHandler): """Simple handler subclass for testing BaseHandler""" + # BaseHandler records the OS environment at import time, but envvars + # might have been changed later by other tests, which trips up + # HandlerTests.testEnviron(). + os_environ = dict(os.environ.items()) + def __init__(self,**kw): setup_testing_defaults(kw) BaseCGIHandler.__init__( From python-checkins at python.org Tue Nov 3 17:43:04 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 03 Nov 2009 16:43:04 -0000 Subject: [Python-checkins] r76087 - in python/branches/release26-maint: Lib/test/test_wsgiref.py Message-ID: Author: antoine.pitrou Date: Tue Nov 3 17:43:03 2009 New Revision: 76087 Log: Merged revisions 76086 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76086 | antoine.pitrou | 2009-11-03 17:41:20 +0100 (mar., 03 nov. 2009) | 3 lines Try to make test_wsgiref less fragile against environment changes by other tests ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_wsgiref.py Modified: python/branches/release26-maint/Lib/test/test_wsgiref.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_wsgiref.py (original) +++ python/branches/release26-maint/Lib/test/test_wsgiref.py Tue Nov 3 17:43:03 2009 @@ -9,7 +9,9 @@ from wsgiref.simple_server import make_server from StringIO import StringIO from SocketServer import BaseServer -import re, sys +import os +import re +import sys from test import test_support @@ -386,6 +388,11 @@ class ErrorHandler(BaseCGIHandler): """Simple handler subclass for testing BaseHandler""" + # BaseHandler records the OS environment at import time, but envvars + # might have been changed later by other tests, which trips up + # HandlerTests.testEnviron(). + os_environ = dict(os.environ.items()) + def __init__(self,**kw): setup_testing_defaults(kw) BaseCGIHandler.__init__( From python-checkins at python.org Tue Nov 3 18:14:00 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 03 Nov 2009 17:14:00 -0000 Subject: [Python-checkins] r76088 - python/branches/py3k/Lib/test/test_xmlrpc_net.py Message-ID: Author: antoine.pitrou Date: Tue Nov 3 18:13:59 2009 New Revision: 76088 Log: Since time.xmlrpc.com is unreliable, add another test to test_xmlrpc_net Modified: python/branches/py3k/Lib/test/test_xmlrpc_net.py Modified: python/branches/py3k/Lib/test/test_xmlrpc_net.py ============================================================================== --- python/branches/py3k/Lib/test/test_xmlrpc_net.py (original) +++ python/branches/py3k/Lib/test/test_xmlrpc_net.py Tue Nov 3 18:13:59 2009 @@ -1,5 +1,6 @@ #!/usr/bin/env python +import collections import errno import socket import sys @@ -17,8 +18,7 @@ try: t0 = server.currentTime.getCurrentTime() except socket.error as e: - print(" test_current_time: skipping test, got error: %s" % e, - file=sys.stderr) + self.skipTest("network error: %s" % e) return # Perform a minimal sanity check on the result, just to be sure @@ -35,6 +35,21 @@ # time on the server should not be too big. self.assertTrue(delta.days <= 1) + def test_python_builders(self): + # Get the list of builders from the XMLRPC buildbot interface at + # python.org. + server = xmlrpclib.ServerProxy("http://www.python.org/dev/buildbot/all/xmlrpc/") + try: + builders = server.getAllBuilders() + except socket.error as e: + self.skipTest("network error: %s" % e) + return + + # Perform a minimal sanity check on the result, just to be sure + # the request means what we think it means. + self.assertIsInstance(builders, collections.Sequence) + self.assertTrue([x for x in builders if "trunk" in x], builders) + def test_main(): support.requires("network") From python-checkins at python.org Tue Nov 3 18:18:49 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 03 Nov 2009 17:18:49 -0000 Subject: [Python-checkins] r76089 - in python/branches/release31-maint: Lib/test/test_xmlrpc_net.py Message-ID: Author: antoine.pitrou Date: Tue Nov 3 18:18:48 2009 New Revision: 76089 Log: Merged revisions 76088 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76088 | antoine.pitrou | 2009-11-03 18:13:59 +0100 (mar., 03 nov. 2009) | 3 lines Since time.xmlrpc.com is unreliable, add another test to test_xmlrpc_net ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_xmlrpc_net.py Modified: python/branches/release31-maint/Lib/test/test_xmlrpc_net.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_xmlrpc_net.py (original) +++ python/branches/release31-maint/Lib/test/test_xmlrpc_net.py Tue Nov 3 18:18:48 2009 @@ -1,5 +1,6 @@ #!/usr/bin/env python +import collections import errno import socket import sys @@ -17,8 +18,7 @@ try: t0 = server.currentTime.getCurrentTime() except socket.error as e: - print(" test_current_time: skipping test, got error: %s" % e, - file=sys.stderr) + self.skipTest("network error: %s" % e) return # Perform a minimal sanity check on the result, just to be sure @@ -35,6 +35,21 @@ # time on the server should not be too big. self.assertTrue(delta.days <= 1) + def test_python_builders(self): + # Get the list of builders from the XMLRPC buildbot interface at + # python.org. + server = xmlrpclib.ServerProxy("http://www.python.org/dev/buildbot/all/xmlrpc/") + try: + builders = server.getAllBuilders() + except socket.error as e: + self.skipTest("network error: %s" % e) + return + + # Perform a minimal sanity check on the result, just to be sure + # the request means what we think it means. + self.assertTrue(isinstance(builders, collections.Sequence), type(builders)) + self.assertTrue([x for x in builders if "trunk" in x], builders) + def test_main(): support.requires("network") From python-checkins at python.org Tue Nov 3 18:20:10 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 03 Nov 2009 17:20:10 -0000 Subject: [Python-checkins] r76090 - in python/branches/py3k: Lib/test/test_wsgiref.py Message-ID: Author: antoine.pitrou Date: Tue Nov 3 18:20:10 2009 New Revision: 76090 Log: Merged revisions 76086 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76086 | antoine.pitrou | 2009-11-03 17:41:20 +0100 (mar., 03 nov. 2009) | 3 lines Try to make test_wsgiref less fragile against environment changes by other tests ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_wsgiref.py Modified: python/branches/py3k/Lib/test/test_wsgiref.py ============================================================================== --- python/branches/py3k/Lib/test/test_wsgiref.py (original) +++ python/branches/py3k/Lib/test/test_wsgiref.py Tue Nov 3 18:20:10 2009 @@ -9,7 +9,9 @@ from wsgiref.simple_server import make_server from io import StringIO, BytesIO, BufferedReader from socketserver import BaseServer -import re, sys +import os +import re +import sys from test import support @@ -444,6 +446,11 @@ class ErrorHandler(BaseCGIHandler): """Simple handler subclass for testing BaseHandler""" + # BaseHandler records the OS environment at import time, but envvars + # might have been changed later by other tests, which trips up + # HandlerTests.testEnviron(). + os_environ = dict(os.environ.items()) + def __init__(self,**kw): setup_testing_defaults(kw) BaseCGIHandler.__init__( From python-checkins at python.org Tue Nov 3 18:21:14 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 03 Nov 2009 17:21:14 -0000 Subject: [Python-checkins] r76091 - in python/branches/release31-maint: Lib/test/test_wsgiref.py Message-ID: Author: antoine.pitrou Date: Tue Nov 3 18:21:14 2009 New Revision: 76091 Log: Merged revisions 76090 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76090 | antoine.pitrou | 2009-11-03 18:20:10 +0100 (mar., 03 nov. 2009) | 9 lines Merged revisions 76086 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76086 | antoine.pitrou | 2009-11-03 17:41:20 +0100 (mar., 03 nov. 2009) | 3 lines Try to make test_wsgiref less fragile against environment changes by other tests ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_wsgiref.py Modified: python/branches/release31-maint/Lib/test/test_wsgiref.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_wsgiref.py (original) +++ python/branches/release31-maint/Lib/test/test_wsgiref.py Tue Nov 3 18:21:14 2009 @@ -9,7 +9,9 @@ from wsgiref.simple_server import make_server from io import StringIO, BytesIO, BufferedReader from socketserver import BaseServer -import re, sys +import os +import re +import sys from test import support @@ -444,6 +446,11 @@ class ErrorHandler(BaseCGIHandler): """Simple handler subclass for testing BaseHandler""" + # BaseHandler records the OS environment at import time, but envvars + # might have been changed later by other tests, which trips up + # HandlerTests.testEnviron(). + os_environ = dict(os.environ.items()) + def __init__(self,**kw): setup_testing_defaults(kw) BaseCGIHandler.__init__( From python-checkins at python.org Tue Nov 3 18:26:45 2009 From: python-checkins at python.org (guido.van.rossum) Date: Tue, 03 Nov 2009 17:26:45 -0000 Subject: [Python-checkins] r76092 - peps/trunk/pep-3003.txt Message-ID: Author: guido.van.rossum Date: Tue Nov 3 18:26:45 2009 New Revision: 76092 Log: Initial checkin of Moratorium PEP. Added: peps/trunk/pep-3003.txt Added: peps/trunk/pep-3003.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-3003.txt Tue Nov 3 18:26:45 2009 @@ -0,0 +1,150 @@ +PEP: 3003 +Title: Python Language Moratorium +Version: $Revision$ +Last-Modified: $Date$ +Author: Brett Cannon, Jesse Noller, Guido van Rossum +Status: Draft +Type: Process +Content-Type: text/x-rst +Created: 21-Oct-2009 +Post-History: + + +Abstract +======== + +This PEP proposes a temporary moratorium (suspension) of all changes +to the Python language syntax, semantics, and built-ins for a period +of at least two years from the release of Python 3.1. + +This suspension of features is designed to allow non-CPython implementations +to "catch up" to the core implementation of the language, help ease adoption +of Python 3.x, and provide a more stable base for the community. + + +Rationale +========= + +This idea was proposed by Guido van Rossum on the python-ideas [1]_ mailing +list. The premise of his email was to slow the alteration of the Python core +syntax, builtins and semantics to allow non-CPython implementations to catch +up to the current state of Python, both 2.x and 3.x. + +Python, as a language is more than the core implementation -- +CPython -- with a rich, mature and vibrant community of implementations, such +as Jython [2]_, IronPython [3]_ and PyPy [4]_ that are a benefit not only to +the community, but to the language itself. + +Still others, such as Unladen Swallow [5]_ (a branch of CPython) seek not to +create an alternative implementation, but rather they seek to enhance the +performance and implementation of CPython itself. + +Python 3.x was a large part of the last several years of Python's +development. Its release, as well as a bevy of changes to the language +introduce by it and the previous 2.6.x releases, puts alternative +implementations at a severe disadvantage in "keeping pace" with core python +development. + +Additionally, many of the changes put into the recent releases of the language +as implemented by CPython have not yet seen widespread usage amongst the +general user population. For example, most users are beholden to the version +of the interpreter (typically CPython) which comes pre-installed with their +operating system. Most OS vendors are just barely beginning to ship Python 2.6 +-- even fewer are shipping Python 3.x. + +As it is expected that Python 2.7 be the effective "end of life" of the Python +2.x code line, with Python 3.x being the future, it is in the best interest of +Python core development to temporarily suspend the alteration of the language +itself to allow all of these external entities to catch up and to assist in +the adoption of, and migration to, Python 3.x + +Finally, the moratorium is intended to free up cycles within core development +to focus on other issues, such as the CPython interpreter and improvements +therein, the standard library, etc. + +This moratorium does not allow for exceptions -- once accepted, any pending +changes to the syntax or semantics of the language will be postponed until the +moratorium is lifted. + +This moratorium does not attempt to apply to any other Python implementation +meaning that if desired other implementations may add features which deviate +from the standard implementation. + + +Details +======= + +Cannot Change +------------- + +* New built-ins +* Language syntax + The grammar file essentially becomes immutable apart from ambiguity + fixes. +* General language semantics + The language operates as-is with only specific exemptions (see + below). + + +Case-by-Case Exemptions +----------------------- + +* New methods on built-ins + The case for adding a method to a built-in object can be made. +* Incorrect language semantics + If the language semantics turn out to be ambiguous or improperly + implemented based on the intention of the original design then the + semantics may change. +* Language semantics that are difficult to implement + Because other VMs have not begun implementing Python 3.x semantics + there is a possibility that certain semantics are too difficult to + replicate. In those cases they can be changed to ease adoption of + Python 3.x by the other VMs. + + +Allowed to Change +----------------- + +* C API + It is entirely acceptable to change the underlying C code of + CPython as long as other restrictions of this moratorium are not + broken. E.g. removing the GIL would be fine assuming certain + operations that are currently atomic remain atomic. +* The standard library + As the standard library is not directly tied to the language + definition it is not covered by this moratorium. +* Backports of 3.x features to to 2.x + The moratorium only affects features that would be new in 3.x. + + +Retroactive +=========== + +It is important to note that the moratorium covers all changes since the +release of Python 3.1. This rule is intended to avoid features being rushed or +smuggled into the CPython source tree while the moratorium is being discussed. + + +Copyright +========= + +This document has been placed in the public domain. + +References +========== + +.. [1] http://mail.python.org/pipermail/python-ideas/2009-October/006305.html +.. [2] http://www.jython.org/ +.. [3] http://www.codeplex.com/IronPython +.. [4] http://codespeak.net/pypy/ +.. [5] http://code.google.com/p/unladen-swallow/ + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 80 + coding: utf-8 + End: From python-checkins at python.org Tue Nov 3 19:23:04 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 03 Nov 2009 18:23:04 -0000 Subject: [Python-checkins] r76093 - python/branches/release26-maint Message-ID: Author: georg.brandl Date: Tue Nov 3 19:23:04 2009 New Revision: 76093 Log: Recorded merge of revisions 76075 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76075 | skip.montanaro | 2009-11-03 02:43:59 +0000 (Di, 03 Nov 2009) | 1 line typo (space-o?) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Nov 3 19:24:38 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 03 Nov 2009 18:24:38 -0000 Subject: [Python-checkins] r76094 - python/branches/py3k Message-ID: Author: georg.brandl Date: Tue Nov 3 19:24:38 2009 New Revision: 76094 Log: Recorded merge of revisions 76075 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76075 | skip.montanaro | 2009-11-03 02:43:59 +0000 (Di, 03 Nov 2009) | 1 line typo (space-o?) ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 3 19:34:27 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 03 Nov 2009 18:34:27 -0000 Subject: [Python-checkins] r76095 - python/trunk/Doc/library/urlparse.rst Message-ID: Author: georg.brandl Date: Tue Nov 3 19:34:27 2009 New Revision: 76095 Log: #7256: add versionadded tags for functions copied from cgi. Modified: python/trunk/Doc/library/urlparse.rst Modified: python/trunk/Doc/library/urlparse.rst ============================================================================== --- python/trunk/Doc/library/urlparse.rst (original) +++ python/trunk/Doc/library/urlparse.rst Tue Nov 3 19:34:27 2009 @@ -121,6 +121,9 @@ Use the :func:`urllib.urlencode` function to convert such dictionaries into query strings. + .. versionadded:: 2.6 + Copied from the :mod:`cgi` module. + .. function:: parse_qsl(qs[, keep_blank_values[, strict_parsing]]) @@ -141,6 +144,10 @@ Use the :func:`urllib.urlencode` function to convert such lists of pairs into query strings. + .. versionadded:: 2.6 + Copied from the :mod:`cgi` module. + + .. function:: urlunparse(parts) Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument From python-checkins at python.org Tue Nov 3 19:35:03 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 03 Nov 2009 18:35:03 -0000 Subject: [Python-checkins] r76096 - in python/branches/release26-maint: Doc/library/urlparse.rst Message-ID: Author: georg.brandl Date: Tue Nov 3 19:35:03 2009 New Revision: 76096 Log: Merged revisions 76095 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76095 | georg.brandl | 2009-11-03 18:34:27 +0000 (Di, 03 Nov 2009) | 1 line #7256: add versionadded tags for functions copied from cgi. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/urlparse.rst Modified: python/branches/release26-maint/Doc/library/urlparse.rst ============================================================================== --- python/branches/release26-maint/Doc/library/urlparse.rst (original) +++ python/branches/release26-maint/Doc/library/urlparse.rst Tue Nov 3 19:35:03 2009 @@ -121,6 +121,9 @@ Use the :func:`urllib.urlencode` function to convert such dictionaries into query strings. + .. versionadded:: 2.6 + Copied from the :mod:`cgi` module. + .. function:: parse_qsl(qs[, keep_blank_values[, strict_parsing]]) @@ -141,6 +144,10 @@ Use the :func:`urllib.urlencode` function to convert such lists of pairs into query strings. + .. versionadded:: 2.6 + Copied from the :mod:`cgi` module. + + .. function:: urlunparse(parts) Construct a URL from a tuple as returned by ``urlparse()``. The *parts* argument From python-checkins at python.org Tue Nov 3 19:35:33 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 03 Nov 2009 18:35:33 -0000 Subject: [Python-checkins] r76097 - python/branches/py3k Message-ID: Author: georg.brandl Date: Tue Nov 3 19:35:33 2009 New Revision: 76097 Log: Blocked revisions 76095 via svnmerge ........ r76095 | georg.brandl | 2009-11-03 18:34:27 +0000 (Di, 03 Nov 2009) | 1 line #7256: add versionadded tags for functions copied from cgi. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 3 19:45:47 2009 From: python-checkins at python.org (guido.van.rossum) Date: Tue, 03 Nov 2009 18:45:47 -0000 Subject: [Python-checkins] r76098 - peps/trunk/pep-3003.txt Message-ID: Author: guido.van.rossum Date: Tue Nov 3 19:45:47 2009 New Revision: 76098 Log: Explicitly allow PEP 382. Modified: peps/trunk/pep-3003.txt Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Tue Nov 3 19:45:47 2009 @@ -115,6 +115,9 @@ definition it is not covered by this moratorium. * Backports of 3.x features to to 2.x The moratorium only affects features that would be new in 3.x. +* Import semantics + For example, PEP 382. After all, import semantics vary between + Python implementations anyway. Retroactive From python-checkins at python.org Tue Nov 3 20:13:11 2009 From: python-checkins at python.org (brett.cannon) Date: Tue, 03 Nov 2009 19:13:11 -0000 Subject: [Python-checkins] r76099 - peps/trunk/pep-3003.txt Message-ID: Author: brett.cannon Date: Tue Nov 3 20:13:11 2009 New Revision: 76099 Log: Add svn keywords. Modified: peps/trunk/pep-3003.txt (props changed) From python-checkins at python.org Tue Nov 3 23:47:07 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 03 Nov 2009 22:47:07 -0000 Subject: [Python-checkins] r76100 - python/branches/release26-maint/Lib/test/test_curses.py Message-ID: Author: r.david.murray Date: Tue Nov 3 23:47:06 2009 New Revision: 76100 Log: Fix backport of test_curses test skip. Modified: python/branches/release26-maint/Lib/test/test_curses.py Modified: python/branches/release26-maint/Lib/test/test_curses.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_curses.py (original) +++ python/branches/release26-maint/Lib/test/test_curses.py Tue Nov 3 23:47:06 2009 @@ -270,7 +270,7 @@ unit_tests() else: if not sys.__stdout__.isatty(): - raise unittest.SkipTest("sys.__stdout__ is not a tty") + raise TestSkipped("sys.__stdout__ is not a tty") # testing setupterm() inside initscr/endwin # causes terminal breakage curses.setupterm(fd=sys.__stdout__.fileno()) From nnorwitz at gmail.com Tue Nov 3 23:50:53 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 3 Nov 2009 17:50:53 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091103225053.GA9323@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 339, 0] references, sum=339 test_zipimport_support leaked [0, 25, 0] references, sum=25 Less important issues: ---------------------- test_threading leaked [48, 48, 48] references, sum=144 From python-checkins at python.org Wed Nov 4 01:50:27 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 00:50:27 -0000 Subject: [Python-checkins] r76101 - python/trunk/Lib/test/test_shutil.py Message-ID: Author: antoine.pitrou Date: Wed Nov 4 01:50:26 2009 New Revision: 76101 Log: Make test_shutil clean up after itself Modified: python/trunk/Lib/test/test_shutil.py Modified: python/trunk/Lib/test/test_shutil.py ============================================================================== --- python/trunk/Lib/test/test_shutil.py (original) +++ python/trunk/Lib/test/test_shutil.py Wed Nov 4 01:50:26 2009 @@ -118,7 +118,7 @@ if os.path.exists(path): os.remove(path) for path in (src_dir, - os.path.abspath(os.path.join(dst_dir, os.path.pardir)) + os.path.dirname(dst_dir) ): if os.path.exists(path): shutil.rmtree(path) @@ -140,65 +140,69 @@ join = os.path.join exists = os.path.exists src_dir = tempfile.mkdtemp() - dst_dir = join(tempfile.mkdtemp(), 'destination') - write_data(join(src_dir, 'test.txt'), '123') - write_data(join(src_dir, 'test.tmp'), '123') - os.mkdir(join(src_dir, 'test_dir')) - write_data(join(src_dir, 'test_dir', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2')) - write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2', 'subdir')) - os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) - write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') - write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') + try: + dst_dir = join(tempfile.mkdtemp(), 'destination') + write_data(join(src_dir, 'test.txt'), '123') + write_data(join(src_dir, 'test.tmp'), '123') + os.mkdir(join(src_dir, 'test_dir')) + write_data(join(src_dir, 'test_dir', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2')) + write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2', 'subdir')) + os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) + write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') + write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') - # testing glob-like patterns - try: - patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(exists(join(dst_dir, 'test.txt'))) - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) - try: - patterns = shutil.ignore_patterns('*.tmp', 'subdir*') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + # testing glob-like patterns + try: + patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(exists(join(dst_dir, 'test.txt'))) + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) + try: + patterns = shutil.ignore_patterns('*.tmp', 'subdir*') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) - # testing callable-style - try: - def _filter(src, names): - res = [] - for name in names: - path = os.path.join(src, name) - - if (os.path.isdir(path) and - path.split()[-1] == 'subdir'): - res.append(name) - elif os.path.splitext(path)[-1] in ('.py'): - res.append(name) - return res - - shutil.copytree(src_dir, dst_dir, ignore=_filter) - - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', - 'test.py'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + # testing callable-style + try: + def _filter(src, names): + res = [] + for name in names: + path = os.path.join(src, name) + + if (os.path.isdir(path) and + path.split()[-1] == 'subdir'): + res.append(name) + elif os.path.splitext(path)[-1] in ('.py'): + res.append(name) + return res + + shutil.copytree(src_dir, dst_dir, ignore=_filter) + + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', + 'test.py'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + shutil.rmtree(src_dir) + shutil.rmtree(os.path.dirname(dst_dir)) if hasattr(os, "symlink"): def test_dont_copy_file_onto_link_to_itself(self): From python-checkins at python.org Wed Nov 4 01:55:26 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 00:55:26 -0000 Subject: [Python-checkins] r76102 - in python/branches/release26-maint: Lib/test/test_shutil.py Message-ID: Author: antoine.pitrou Date: Wed Nov 4 01:55:26 2009 New Revision: 76102 Log: Merged revisions 76101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76101 | antoine.pitrou | 2009-11-04 01:50:26 +0100 (mer., 04 nov. 2009) | 3 lines Make test_shutil clean up after itself ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_shutil.py Modified: python/branches/release26-maint/Lib/test/test_shutil.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_shutil.py (original) +++ python/branches/release26-maint/Lib/test/test_shutil.py Wed Nov 4 01:55:26 2009 @@ -103,7 +103,7 @@ if os.path.exists(path): os.remove(path) for path in (src_dir, - os.path.abspath(os.path.join(dst_dir, os.path.pardir)) + os.path.dirname(dst_dir) ): if os.path.exists(path): shutil.rmtree(path) @@ -125,65 +125,68 @@ join = os.path.join exists = os.path.exists src_dir = tempfile.mkdtemp() - dst_dir = join(tempfile.mkdtemp(), 'destination') - write_data(join(src_dir, 'test.txt'), '123') - write_data(join(src_dir, 'test.tmp'), '123') - os.mkdir(join(src_dir, 'test_dir')) - write_data(join(src_dir, 'test_dir', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2')) - write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2', 'subdir')) - os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) - write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') - write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') - - - # testing glob-like patterns - try: - patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assert_(exists(join(dst_dir, 'test.txt'))) - self.assert_(not exists(join(dst_dir, 'test.tmp'))) - self.assert_(not exists(join(dst_dir, 'test_dir2'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) try: - patterns = shutil.ignore_patterns('*.tmp', 'subdir*') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assert_(not exists(join(dst_dir, 'test.tmp'))) - self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) - self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + dst_dir = join(tempfile.mkdtemp(), 'destination') + write_data(join(src_dir, 'test.txt'), '123') + write_data(join(src_dir, 'test.tmp'), '123') + os.mkdir(join(src_dir, 'test_dir')) + write_data(join(src_dir, 'test_dir', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2')) + write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2', 'subdir')) + os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) + write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') + write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') - # testing callable-style - try: - def _filter(src, names): - res = [] - for name in names: - path = os.path.join(src, name) - - if (os.path.isdir(path) and - path.split()[-1] == 'subdir'): - res.append(name) - elif os.path.splitext(path)[-1] in ('.py'): - res.append(name) - return res - - shutil.copytree(src_dir, dst_dir, ignore=_filter) - - # checking the result: some elements should not be copied - self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir2', - 'test.py'))) - self.assert_(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + # testing glob-like patterns + try: + patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(exists(join(dst_dir, 'test.txt'))) + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) + try: + patterns = shutil.ignore_patterns('*.tmp', 'subdir*') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) + # testing callable-style + try: + def _filter(src, names): + res = [] + for name in names: + path = os.path.join(src, name) + + if (os.path.isdir(path) and + path.split()[-1] == 'subdir'): + res.append(name) + elif os.path.splitext(path)[-1] in ('.py'): + res.append(name) + return res + + shutil.copytree(src_dir, dst_dir, ignore=_filter) + + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', + 'test.py'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + shutil.rmtree(src_dir) + shutil.rmtree(os.path.dirname(dst_dir)) if hasattr(os, "symlink"): def test_dont_copy_file_onto_link_to_itself(self): From python-checkins at python.org Wed Nov 4 01:57:15 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 00:57:15 -0000 Subject: [Python-checkins] r76103 - in python/branches/py3k: Lib/test/test_shutil.py Message-ID: Author: antoine.pitrou Date: Wed Nov 4 01:57:15 2009 New Revision: 76103 Log: Merged revisions 76101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76101 | antoine.pitrou | 2009-11-04 01:50:26 +0100 (mer., 04 nov. 2009) | 3 lines Make test_shutil clean up after itself ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_shutil.py Modified: python/branches/py3k/Lib/test/test_shutil.py ============================================================================== --- python/branches/py3k/Lib/test/test_shutil.py (original) +++ python/branches/py3k/Lib/test/test_shutil.py Wed Nov 4 01:57:15 2009 @@ -118,7 +118,7 @@ if os.path.exists(path): os.remove(path) for path in (src_dir, - os.path.abspath(os.path.join(dst_dir, os.path.pardir)) + os.path.dirname(dst_dir) ): if os.path.exists(path): shutil.rmtree(path) @@ -140,65 +140,69 @@ join = os.path.join exists = os.path.exists src_dir = tempfile.mkdtemp() - dst_dir = join(tempfile.mkdtemp(), 'destination') - write_data(join(src_dir, 'test.txt'), '123') - write_data(join(src_dir, 'test.tmp'), '123') - os.mkdir(join(src_dir, 'test_dir')) - write_data(join(src_dir, 'test_dir', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2')) - write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2', 'subdir')) - os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) - write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') - write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') + try: + dst_dir = join(tempfile.mkdtemp(), 'destination') + write_data(join(src_dir, 'test.txt'), '123') + write_data(join(src_dir, 'test.tmp'), '123') + os.mkdir(join(src_dir, 'test_dir')) + write_data(join(src_dir, 'test_dir', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2')) + write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2', 'subdir')) + os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) + write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') + write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') - # testing glob-like patterns - try: - patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(exists(join(dst_dir, 'test.txt'))) - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) - try: - patterns = shutil.ignore_patterns('*.tmp', 'subdir*') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + # testing glob-like patterns + try: + patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(exists(join(dst_dir, 'test.txt'))) + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) + try: + patterns = shutil.ignore_patterns('*.tmp', 'subdir*') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) - # testing callable-style - try: - def _filter(src, names): - res = [] - for name in names: - path = os.path.join(src, name) - - if (os.path.isdir(path) and - path.split()[-1] == 'subdir'): - res.append(name) - elif os.path.splitext(path)[-1] in ('.py'): - res.append(name) - return res - - shutil.copytree(src_dir, dst_dir, ignore=_filter) - - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', - 'test.py'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + # testing callable-style + try: + def _filter(src, names): + res = [] + for name in names: + path = os.path.join(src, name) + + if (os.path.isdir(path) and + path.split()[-1] == 'subdir'): + res.append(name) + elif os.path.splitext(path)[-1] in ('.py'): + res.append(name) + return res + + shutil.copytree(src_dir, dst_dir, ignore=_filter) + + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', + 'test.py'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + shutil.rmtree(src_dir) + shutil.rmtree(os.path.dirname(dst_dir)) if hasattr(os, "symlink"): def test_dont_copy_file_onto_link_to_itself(self): From python-checkins at python.org Wed Nov 4 02:00:48 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 01:00:48 -0000 Subject: [Python-checkins] r76104 - in python/branches/release31-maint: Lib/test/test_shutil.py Message-ID: Author: antoine.pitrou Date: Wed Nov 4 02:00:48 2009 New Revision: 76104 Log: Merged revisions 76103 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76103 | antoine.pitrou | 2009-11-04 01:57:15 +0100 (mer., 04 nov. 2009) | 9 lines Merged revisions 76101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76101 | antoine.pitrou | 2009-11-04 01:50:26 +0100 (mer., 04 nov. 2009) | 3 lines Make test_shutil clean up after itself ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_shutil.py Modified: python/branches/release31-maint/Lib/test/test_shutil.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_shutil.py (original) +++ python/branches/release31-maint/Lib/test/test_shutil.py Wed Nov 4 02:00:48 2009 @@ -118,7 +118,7 @@ if os.path.exists(path): os.remove(path) for path in (src_dir, - os.path.abspath(os.path.join(dst_dir, os.path.pardir)) + os.path.dirname(dst_dir) ): if os.path.exists(path): shutil.rmtree(path) @@ -140,65 +140,69 @@ join = os.path.join exists = os.path.exists src_dir = tempfile.mkdtemp() - dst_dir = join(tempfile.mkdtemp(), 'destination') - write_data(join(src_dir, 'test.txt'), '123') - write_data(join(src_dir, 'test.tmp'), '123') - os.mkdir(join(src_dir, 'test_dir')) - write_data(join(src_dir, 'test_dir', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2')) - write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2', 'subdir')) - os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) - write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') - write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') + try: + dst_dir = join(tempfile.mkdtemp(), 'destination') + write_data(join(src_dir, 'test.txt'), '123') + write_data(join(src_dir, 'test.tmp'), '123') + os.mkdir(join(src_dir, 'test_dir')) + write_data(join(src_dir, 'test_dir', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2')) + write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2', 'subdir')) + os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) + write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') + write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') - # testing glob-like patterns - try: - patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(exists(join(dst_dir, 'test.txt'))) - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) - try: - patterns = shutil.ignore_patterns('*.tmp', 'subdir*') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + # testing glob-like patterns + try: + patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(exists(join(dst_dir, 'test.txt'))) + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) + try: + patterns = shutil.ignore_patterns('*.tmp', 'subdir*') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) - # testing callable-style - try: - def _filter(src, names): - res = [] - for name in names: - path = os.path.join(src, name) - - if (os.path.isdir(path) and - path.split()[-1] == 'subdir'): - res.append(name) - elif os.path.splitext(path)[-1] in ('.py'): - res.append(name) - return res - - shutil.copytree(src_dir, dst_dir, ignore=_filter) - - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', - 'test.py'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + # testing callable-style + try: + def _filter(src, names): + res = [] + for name in names: + path = os.path.join(src, name) + + if (os.path.isdir(path) and + path.split()[-1] == 'subdir'): + res.append(name) + elif os.path.splitext(path)[-1] in ('.py'): + res.append(name) + return res + + shutil.copytree(src_dir, dst_dir, ignore=_filter) + + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', + 'test.py'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + shutil.rmtree(src_dir) + shutil.rmtree(os.path.dirname(dst_dir)) if hasattr(os, "symlink"): def test_dont_copy_file_onto_link_to_itself(self): From python-checkins at python.org Wed Nov 4 08:38:12 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 04 Nov 2009 07:38:12 -0000 Subject: [Python-checkins] r76105 - in python/trunk: Doc/library/operator.rst Modules/operator.c Message-ID: Author: georg.brandl Date: Wed Nov 4 08:38:12 2009 New Revision: 76105 Log: #7259: show correct equivalent for operator.i* operations in docstring; fix minor issues in operator docs. Modified: python/trunk/Doc/library/operator.rst python/trunk/Modules/operator.c Modified: python/trunk/Doc/library/operator.rst ============================================================================== --- python/trunk/Doc/library/operator.rst (original) +++ python/trunk/Doc/library/operator.rst Wed Nov 4 08:38:12 2009 @@ -117,6 +117,14 @@ .. versionadded:: 2.2 +.. function:: index(a) + __index__(a) + + Return *a* converted to an integer. Equivalent to ``a.__index__()``. + + .. versionadded:: 2.5 + + .. function:: inv(obj) invert(obj) __inv__(obj) @@ -149,7 +157,7 @@ .. function:: neg(obj) __neg__(obj) - Return *obj* negated. + Return *obj* negated (``-obj``). .. function:: or_(a, b) @@ -161,7 +169,7 @@ .. function:: pos(obj) __pos__(obj) - Return *obj* positive. + Return *obj* positive (``+obj``). .. function:: pow(a, b) @@ -199,15 +207,7 @@ Return the bitwise exclusive or of *a* and *b*. -.. function:: index(a) - __index__(a) - - Return *a* converted to an integer. Equivalent to ``a.__index__()``. - - .. versionadded:: 2.5 - - -Operations which work with sequences include: +Operations which work with sequences (some of them with mappings too) include: .. function:: concat(a, b) __concat__(a, b) @@ -359,7 +359,7 @@ .. function:: ilshift(a, b) __ilshift__(a, b) - ``a = ilshift(a, b)`` is equivalent to ``a <``\ ``<= b``. + ``a = ilshift(a, b)`` is equivalent to ``a <<= b``. .. versionadded:: 2.5 @@ -572,79 +572,81 @@ This table shows how abstract operations correspond to operator symbols in the Python syntax and the functions in the :mod:`operator` module. -+-----------------------+-------------------------+---------------------------------+ -| Operation | Syntax | Function | -+=======================+=========================+=================================+ -| Addition | ``a + b`` | ``add(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Concatenation | ``seq1 + seq2`` | ``concat(seq1, seq2)`` | -+-----------------------+-------------------------+---------------------------------+ -| Containment Test | ``obj in seq`` | ``contains(seq, obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a / b`` | ``div(a, b)`` (without | -| | | ``__future__.division``) | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a / b`` | ``truediv(a, b)`` (with | -| | | ``__future__.division``) | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a // b`` | ``floordiv(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise And | ``a & b`` | ``and_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Exclusive Or | ``a ^ b`` | ``xor(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Inversion | ``~ a`` | ``invert(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Or | ``a | b`` | ``or_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Exponentiation | ``a ** b`` | ``pow(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Identity | ``a is b`` | ``is_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Identity | ``a is not b`` | ``is_not(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexed Assignment | ``obj[k] = v`` | ``setitem(obj, k, v)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexed Deletion | ``del obj[k]`` | ``delitem(obj, k)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexing | ``obj[k]`` | ``getitem(obj, k)`` | -+-----------------------+-------------------------+---------------------------------+ -| Left Shift | ``a << b`` | ``lshift(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Modulo | ``a % b`` | ``mod(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Multiplication | ``a * b`` | ``mul(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Negation (Arithmetic) | ``- a`` | ``neg(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Negation (Logical) | ``not a`` | ``not_(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Right Shift | ``a >> b`` | ``rshift(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Sequence Repetition | ``seq * i`` | ``repeat(seq, i)`` | -+-----------------------+-------------------------+---------------------------------+ -| Slice Assignment | ``seq[i:j] = values`` | ``setslice(seq, i, j, values)`` | -+-----------------------+-------------------------+---------------------------------+ -| Slice Deletion | ``del seq[i:j]`` | ``delslice(seq, i, j)`` | -+-----------------------+-------------------------+---------------------------------+ -| Slicing | ``seq[i:j]`` | ``getslice(seq, i, j)`` | -+-----------------------+-------------------------+---------------------------------+ -| String Formatting | ``s % obj`` | ``mod(s, obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Subtraction | ``a - b`` | ``sub(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Truth Test | ``obj`` | ``truth(obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a < b`` | ``lt(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a <= b`` | ``le(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Equality | ``a == b`` | ``eq(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Difference | ``a != b`` | ``ne(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a >= b`` | ``ge(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a > b`` | ``gt(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ ++-----------------------+-------------------------+---------------------------------------+ +| Operation | Syntax | Function | ++=======================+=========================+=======================================+ +| Addition | ``a + b`` | ``add(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Concatenation | ``seq1 + seq2`` | ``concat(seq1, seq2)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Containment Test | ``obj in seq`` | ``contains(seq, obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a / b`` | ``div(a, b)`` (without | +| | | ``__future__.division``) | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a / b`` | ``truediv(a, b)`` (with | +| | | ``__future__.division``) | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a // b`` | ``floordiv(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise And | ``a & b`` | ``and_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Exclusive Or | ``a ^ b`` | ``xor(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Inversion | ``~ a`` | ``invert(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Or | ``a | b`` | ``or_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Exponentiation | ``a ** b`` | ``pow(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Identity | ``a is b`` | ``is_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Identity | ``a is not b`` | ``is_not(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexed Assignment | ``obj[k] = v`` | ``setitem(obj, k, v)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexed Deletion | ``del obj[k]`` | ``delitem(obj, k)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexing | ``obj[k]`` | ``getitem(obj, k)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Left Shift | ``a << b`` | ``lshift(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Modulo | ``a % b`` | ``mod(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Multiplication | ``a * b`` | ``mul(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Negation (Arithmetic) | ``- a`` | ``neg(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Negation (Logical) | ``not a`` | ``not_(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Positive | ``+ a`` | ``pos(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Right Shift | ``a >> b`` | ``rshift(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Sequence Repetition | ``seq * i`` | ``repeat(seq, i)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slice Assignment | ``seq[i:j] = values`` | ``setitem(seq, slice(i, j), values)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slice Deletion | ``del seq[i:j]`` | ``delitem(seq, slice(i, j))`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slicing | ``seq[i:j]`` | ``getitem(seq, slice(i, j))`` | ++-----------------------+-------------------------+---------------------------------------+ +| String Formatting | ``s % obj`` | ``mod(s, obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Subtraction | ``a - b`` | ``sub(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Truth Test | ``obj`` | ``truth(obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a < b`` | ``lt(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a <= b`` | ``le(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Equality | ``a == b`` | ``eq(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Difference | ``a != b`` | ``ne(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a >= b`` | ``ge(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a > b`` | ``gt(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ Modified: python/trunk/Modules/operator.c ============================================================================== --- python/trunk/Modules/operator.c (original) +++ python/trunk/Modules/operator.c Wed Nov 4 08:38:12 2009 @@ -7,7 +7,7 @@ This module exports a set of functions implemented in C corresponding\n\ to the intrinsic operators of Python. For example, operator.add(x, y)\n\ is equivalent to the expression x+y. The function names are those\n\ -used for special class methods; variants without leading and trailing\n\ +used for special methods; variants without leading and trailing\n\ '__' are also provided for convenience."); #define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \ @@ -277,26 +277,26 @@ spam2(and_,__and__, "and_(a, b) -- Same as a & b.") spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.") spam2(or_,__or__, "or_(a, b) -- Same as a | b.") -spam2(iadd,__iadd__, "iadd(a, b) -- Same as a += b.") -spam2(isub,__isub__, "isub(a, b) -- Same as a -= b.") -spam2(imul,__imul__, "imul(a, b) -- Same as a *= b.") -spam2(idiv,__idiv__, "idiv(a, b) -- Same as a /= b when __future__.division is not in effect.") -spam2(ifloordiv,__ifloordiv__, "ifloordiv(a, b) -- Same as a //= b.") -spam2(itruediv,__itruediv__, "itruediv(a, b) -- Same as a /= b when __future__.division is in effect.") -spam2(imod,__imod__, "imod(a, b) -- Same as a %= b.") -spam2(ilshift,__ilshift__, "ilshift(a, b) -- Same as a <<= b.") -spam2(irshift,__irshift__, "irshift(a, b) -- Same as a >>= b.") -spam2(iand,__iand__, "iand(a, b) -- Same as a &= b.") -spam2(ixor,__ixor__, "ixor(a, b) -- Same as a ^= b.") -spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.") +spam2(iadd,__iadd__, "a = iadd(a, b) -- Same as a += b.") +spam2(isub,__isub__, "a = isub(a, b) -- Same as a -= b.") +spam2(imul,__imul__, "a = imul(a, b) -- Same as a *= b.") +spam2(idiv,__idiv__, "a = idiv(a, b) -- Same as a /= b when __future__.division is not in effect.") +spam2(ifloordiv,__ifloordiv__, "a = ifloordiv(a, b) -- Same as a //= b.") +spam2(itruediv,__itruediv__, "a = itruediv(a, b) -- Same as a /= b when __future__.division is in effect.") +spam2(imod,__imod__, "a = imod(a, b) -- Same as a %= b.") +spam2(ilshift,__ilshift__, "a = ilshift(a, b) -- Same as a <<= b.") +spam2(irshift,__irshift__, "a = irshift(a, b) -- Same as a >>= b.") +spam2(iand,__iand__, "a = iand(a, b) -- Same as a &= b.") +spam2(ixor,__ixor__, "a = ixor(a, b) -- Same as a ^= b.") +spam2(ior,__ior__, "a = ior(a, b) -- Same as a |= b.") spam2(concat,__concat__, "concat(a, b) -- Same as a + b, for a and b sequences.") spam2(repeat,__repeat__, "repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.") spam2(iconcat,__iconcat__, - "iconcat(a, b) -- Same as a += b, for a and b sequences.") + "a = iconcat(a, b) -- Same as a += b, for a and b sequences.") spam2(irepeat,__irepeat__, - "irepeat(a, b) -- Same as a *= b, where a is a sequence, and b is an integer.") + "a = irepeat(a, b) -- Same as a *= b, where a is a sequence, and b is an integer.") spam2(getitem,__getitem__, "getitem(a, b) -- Same as a[b].") spam2(setitem,__setitem__, @@ -304,7 +304,7 @@ spam2(delitem,__delitem__, "delitem(a, b) -- Same as del a[b].") spam2(pow,__pow__, "pow(a, b) -- Same as a ** b.") -spam2(ipow,__ipow__, "ipow(a, b) -- Same as a **= b.") +spam2(ipow,__ipow__, "a = ipow(a, b) -- Same as a **= b.") spam2(getslice,__getslice__, "getslice(a, b, c) -- Same as a[b:c].") spam2(setslice,__setslice__, From python-checkins at python.org Wed Nov 4 12:47:20 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 04 Nov 2009 11:47:20 -0000 Subject: [Python-checkins] r76106 - python/branches/tarek_sysconfig Message-ID: Author: tarek.ziade Date: Wed Nov 4 12:47:20 2009 New Revision: 76106 Log: added a branch for sysconfig module work Added: python/branches/tarek_sysconfig/ - copied from r76105, /python/trunk/ From python-checkins at python.org Wed Nov 4 13:09:46 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 04 Nov 2009 12:09:46 -0000 Subject: [Python-checkins] r76107 - in python/branches/tarek_sysconfig/Lib: sysconfig.py test/test_sysconfig.py Message-ID: Author: tarek.ziade Date: Wed Nov 4 13:09:46 2009 New Revision: 76107 Log: first draft of sysconfig module (refactoring of site/distutils.command.install/distutils.sysconfig) Added: python/branches/tarek_sysconfig/Lib/sysconfig.py python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Added: python/branches/tarek_sysconfig/Lib/sysconfig.py ============================================================================== --- (empty file) +++ python/branches/tarek_sysconfig/Lib/sysconfig.py Wed Nov 4 13:09:46 2009 @@ -0,0 +1,589 @@ +import sys +import os +from os.path import pardir, abspath + +_INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', + 'platlib': '$platbase/lib/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', + 'platlib': '$base/lib/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'nt': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + 'mac': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + + 'os2': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + 'nt_user': { + 'purelib': '$userbase/Python/$py_version_nodot/site-packages', + 'platlib': '$userbase/Python/$py_version_nodot/site-packages', + 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', + 'scripts': '$userbase/Scripts', + 'data' : '$userbase', + }, + 'unix_user': { + 'purelib': '$userbase/lib/python/$py_version_short/site-packages', + 'platlib': '$userbase/lib/python/$py_version_short/site-packages', + 'headers': '$userbase/include/python$py_version_short/$dist_name', + 'scripts': '$userbase/bin', + 'data' : '$userbase', + }, + 'mac_user': { + 'purelib': '$userbase/lib/python/$py_version_short/site-packages', + 'platlib': '$userbase/lib/python/$py_version_short/site-packages', + 'headers': '$userbase/$py_version_short/include/$dist_name', + 'scripts': '$userbase/bin', + 'data' : '$userbase', + }, + 'os2_home': { + 'purelib': '$userbase/lib/python/$py_version_short/site-packages', + 'platlib': '$userbase/lib/python/$py_version_short/site-packages', + 'headers': '$userbase/include/python$py_version_short/$dist_name', + 'scripts': '$userbase/bin', + 'data' : '$userbase', + } + } + +_SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') +_PY_VERSION = sys.version.split()[0] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None +_PROJECT_BASE = os.path.dirname(abspath(sys.executable)) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = abspath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = abspath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = abspath(os.path.join(_PROJECT_BASE, pardir, pardir)) + +def _python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = _python_build() + +def get_python_version(): + """Return a string containing the major and minor Python version, + leaving off the patchlevel. Sample return values could be '1.5' + or '2.2'. + """ + return sys.version[:3] + +def _subst_vars(s, local_vars): + import re + def _subst(match, local_vars=local_vars): + var_name = match.group(1) + if var_name in local_vars: + return str(local_vars[var_name]) + else: + return os.environ[var_name] + try: + return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) + except KeyError, var: + raise AttributeError('$%s' % var) + +def _expand_vars(scheme, vars): + res = {} + for key, value in _INSTALL_SCHEMES[scheme].items(): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + vars = get_config_vars() + res[key] = _subst_vars(value, vars) + return res + +def _get_default_scheme(): + if os.name == 'posix': + return 'unix_home' + return os.name + +def get_paths(scheme=_get_default_scheme(), vars=None): + """Returns a mapping containing the install scheme. + + ``scheme`` is the install scheme name + """ + return _expand_vars(scheme, vars) + +def get_path(scheme, name, vars=None): + """Returns a mapping containing the install scheme. + + ``scheme`` is the install scheme name + """ + return _expand_vars(scheme, vars)[name] + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + return env_base if env_base else joinuser(base, "Python") + + return env_base if env_base else joinuser("~", ".local") + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. Generally this includes + everything needed to build extensions and install both pure modules and + extensions. On Unix, this means every variable defined in Python's + installed Makefile; on Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + import re + global _CONFIG_VARS + if _CONFIG_VARS is None: + func = globals().get("_init_" + os.name) + if func: + func() + else: + _CONFIG_VARS = {} + + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION[3:0] + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['userbase'] = _getuserbase() + _CONFIG_VARS['dist_name'] = '' + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = os.path.dirname(abspath(sys.executable)) + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != os.getcwd()): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # 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', + # 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) + _CONFIG_VARS[key] = flags + + else: + + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + 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 = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search('-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + 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('-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + +def get_config_var(name): + """Return the value of a single variable using the dictionary + returned by 'get_CONFIG_VARS()'. Equivalent to + get_CONFIG_VARS().get(name) + """ + return get_config_vars().get(name) + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile (r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + + macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET') + if not macver: + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if 1: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + m = re.search( + r'ProductUserVisibleVersion\s*' + + r'(.*?)', f.read()) + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if (macrelease + '.') >= '10.4.' and \ + '-arch' in get_config_vars().get('CFLAGS', '').strip(): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall('-arch\s+(\S+)', cflags) + archs.sort() + archs = tuple(archs) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r"%(archs,)) + + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_inc(plat_specific=0, prefix=None): + """Return the directory containing installed Python header files. + + If 'plat_specific' is false (the default), this is the path to the + non-platform-specific header files, i.e. Python.h and so on; + otherwise, this is the path to platform-specific header files + (namely pyconfig.h). + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + if prefix is None: + prefix = plat_specific and _EXEC_PREFIX or _PREFIX + if os.name == "posix": + if _PYTHON_BUILD: + # Assume the executable is in the build directory. The + # pyconfig.h file should be in the same directory. Since + # the build directory may not be the source directory, we + # must use "srcdir" from the makefile to find the "Include" + # directory. + base = os.path.dirname(os.path.abspath(sys.executable)) + if plat_specific: + return base + else: + incdir = os.path.join(get_config_var('srcdir'), 'Include') + return os.path.normpath(incdir) + return os.path.join(prefix, "include", "python" + get_python_version()) + elif os.name == "nt": + return os.path.join(prefix, "include") + elif os.name == "mac": + if plat_specific: + return os.path.join(prefix, "Mac", "Include") + else: + return os.path.join(prefix, "Include") + elif os.name == "os2": + return os.path.join(prefix, "Include") + else: + raise DistutilsPlatformError( + "I don't know where Python installs its C header files " + "on platform '%s'" % os.name) + +def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + """Return the directory containing the Python library (standard or + site additions). + + If 'plat_specific' is true, return the directory containing + platform-specific modules, i.e. any module from a non-pure-Python + module distribution; otherwise, return the platform-shared library + directory. If 'standard_lib' is true, return the directory + containing standard Python library modules; otherwise, return the + directory for site-specific modules. + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + if prefix is None: + prefix = plat_specific and _EXEC_PREFIX or _PREFIX + + if os.name == "posix": + libpython = os.path.join(prefix, + "lib", "python" + get_python_version()) + if standard_lib: + return libpython + else: + return os.path.join(libpython, "site-packages") + + elif os.name == "nt": + if standard_lib: + return os.path.join(prefix, "Lib") + else: + if get_python_version() < "2.2": + return prefix + else: + return os.path.join(prefix, "Lib", "site-packages") + + elif os.name == "mac": + if plat_specific: + if standard_lib: + return os.path.join(prefix, "Lib", "lib-dynload") + else: + return os.path.join(prefix, "Lib", "site-packages") + else: + if standard_lib: + return os.path.join(prefix, "Lib") + else: + return os.path.join(prefix, "Lib", "site-packages") + + elif os.name == "os2": + if standard_lib: + return os.path.join(prefix, "Lib") + else: + return os.path.join(prefix, "Lib", "site-packages") + + else: + raise DistutilsPlatformError( + "I don't know where Python installs its library " + "on platform '%s'" % os.name) + + +def get_config_h_filename(): + """Return full pathname of installed pyconfig.h file.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(project_base, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_python_inc(plat_specific=1) + if get_python_version() < '2.2': + config_h = 'config.h' + else: + # The name of the config.h file changed in 2.2 + config_h = 'pyconfig.h' + return os.path.join(inc_dir, config_h) + + +def get_makefile_filename(): + """Return full pathname of installed Makefile from the Python build.""" + if _PYTHON_BUILD: + return os.path.join(os.path.dirname(sys.executable), "Makefile") + lib_dir = get_python_lib(plat_specific=1, standard_lib=1) + return os.path.join(lib_dir, "config", "Makefile") + +def parse_config_h(fp, g=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if g is None: + g = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + # + while 1: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: v = int(v) + except ValueError: pass + g[n] = v + else: + m = undef_rx.match(line) + if m: + g[m.group(1)] = 0 + return g Added: python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py ============================================================================== --- (empty file) +++ python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Wed Nov 4 13:09:46 2009 @@ -0,0 +1,88 @@ +"""Tests for 'site'. + +Tests assume the initial paths in sys.path once the interpreter has begun +executing have not been removed. + +""" +import unittest +import sys +import test +import os +from test.test_support import run_unittest, TESTFN +from sysconfig import * +from sysconfig import _INSTALL_SCHEMES, _SCHEME_KEYS + +class TestSysConfig(unittest.TestCase): + + def setUp(self): + """Make a copy of sys.path""" + super(TestSysConfig, self).setUp() + self.sys_path = sys.path[:] + self.makefile = None + + def tearDown(self): + """Restore sys.path""" + sys.path[:] = self.sys_path + if self.makefile is not None: + os.unlink(self.makefile) + self._cleanup_testfn() + super(TestSysConfig, self).tearDown() + + def _cleanup_testfn(self): + path = test.test_support.TESTFN + if os.path.isfile(path): + os.remove(path) + elif os.path.isdir(path): + shutil.rmtree(path) + + def test_get_paths(self): + # XXX make it os independant + scheme = get_paths() + wanted = {'purelib': '/usr/local/lib/python', + 'headers': '/usr/local/include/python/', + 'platlib': '/usr/local/lib/python', + 'data': '/usr/local', + 'scripts': '/usr/local/bin'} + + wanted = wanted.items() + wanted.sort() + scheme = scheme.items() + scheme.sort() + self.assertEquals(scheme, wanted) + + def test_get_path(self): + for key in _INSTALL_SCHEMES: + for name in _SCHEME_KEYS: + res = get_path(key, name) + + def test_get_config_h_filename(self): + config_h = get_config_h_filename() + self.assertTrue(os.path.isfile(config_h), config_h) + + def test_get_python_lib(self): + lib_dir = get_python_lib() + # XXX doesn't work on Linux when Python was never installed before + #self.assertTrue(os.path.isdir(lib_dir), lib_dir) + # test for pythonxx.lib? + self.assertNotEqual(get_python_lib(), + get_python_lib(prefix=TESTFN)) + + def test_get_python_inc(self): + inc_dir = get_python_inc() + # This is not much of a test. We make sure Python.h exists + # in the directory returned by get_python_inc() but we don't know + # it is the correct file. + self.assertTrue(os.path.isdir(inc_dir), inc_dir) + python_h = os.path.join(inc_dir, "Python.h") + self.assertTrue(os.path.isfile(python_h), python_h) + + def test_get_config_vars(self): + cvars = get_config_vars() + self.assertTrue(isinstance(cvars, dict)) + self.assertTrue(cvars) + +def test_main(): + run_unittest(TestSysConfig) + +if __name__ == "__main__": + test_main() From python-checkins at python.org Wed Nov 4 20:25:15 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 19:25:15 -0000 Subject: [Python-checkins] r76108 - in python/trunk: Lib/test/test_kqueue.py Misc/ACKS Misc/NEWS Modules/selectmodule.c Message-ID: Author: antoine.pitrou Date: Wed Nov 4 20:25:14 2009 New Revision: 76108 Log: Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent objects on 64-bit systems. Patch by Michael Broghton. I will revert this checkin if it causes problems on our BSD buildbots. Modified: python/trunk/Lib/test/test_kqueue.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS python/trunk/Modules/selectmodule.c Modified: python/trunk/Lib/test/test_kqueue.py ============================================================================== --- python/trunk/Lib/test/test_kqueue.py (original) +++ python/trunk/Lib/test/test_kqueue.py Wed Nov 4 20:25:14 2009 @@ -70,6 +70,17 @@ self.assertEqual(ev, ev) self.assertNotEqual(ev, other) + bignum = sys.maxsize * 2 + 1 + ev = select.kevent(bignum, 1, 2, 3, sys.maxsize, bignum) + self.assertEqual(ev.ident, bignum) + self.assertEqual(ev.filter, 1) + self.assertEqual(ev.flags, 2) + self.assertEqual(ev.fflags, 3) + self.assertEqual(ev.data, sys.maxsize) + self.assertEqual(ev.udata, bignum) + self.assertEqual(ev, ev) + self.assertNotEqual(ev, other) + def test_queue_event(self): serverSocket = socket.socket() serverSocket.bind(('127.0.0.1', 0)) Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Nov 4 20:25:14 2009 @@ -96,6 +96,7 @@ Dave Brennan Tom Bridgman Richard Brodie +Michael Broghton Daniel Brotsky Jean Brouwers Gary S. Brown Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 4 20:25:14 2009 @@ -426,6 +426,9 @@ Library ------- +- Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent + objects on 64-bit systems. Patch by Michael Broghton. + - Issue #6896: mailbox.Maildir now invalidates its internal cache each time a modification is done through it. This fixes inconsistencies and test failures on systems with slightly bogus mtime behaviour. Modified: python/trunk/Modules/selectmodule.c ============================================================================== --- python/trunk/Modules/selectmodule.c (original) +++ python/trunk/Modules/selectmodule.c Wed Nov 4 20:25:14 2009 @@ -1194,6 +1194,30 @@ #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type)) +#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) +# error uintptr_t does not match void *! +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) +# define T_UINTPTRT T_ULONGLONG +# define T_INTPTRT T_LONGLONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong +# define UINTPTRT_FMT_UNIT "K" +# define INTPTRT_FMT_UNIT "L" +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) +# define T_UINTPTRT T_ULONG +# define T_INTPTRT T_LONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "k" +# define INTPTRT_FMT_UNIT "l" +#elif (SIZEOF_UINTPTR_T == SIZEOF_INT) +# define T_UINTPTRT T_UINT +# define T_INTPTRT T_INT +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "I" +# define INTPTRT_FMT_UNIT "i" +#else +# error uintptr_t does not match int, long, or long long! +#endif + /* Unfortunately, we can't store python objects in udata, because * kevents in the kernel can be removed without warning, which would * forever lose the refcount on the object stored with it. @@ -1201,12 +1225,12 @@ #define KQ_OFF(x) offsetof(kqueue_event_Object, x) static struct PyMemberDef kqueue_event_members[] = { - {"ident", T_UINT, KQ_OFF(e.ident)}, + {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, {"filter", T_SHORT, KQ_OFF(e.filter)}, {"flags", T_USHORT, KQ_OFF(e.flags)}, {"fflags", T_UINT, KQ_OFF(e.fflags)}, - {"data", T_INT, KQ_OFF(e.data)}, - {"udata", T_INT, KQ_OFF(e.udata)}, + {"data", T_INTPTRT, KQ_OFF(e.data)}, + {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, {NULL} /* Sentinel */ }; #undef KQ_OFF @@ -1217,10 +1241,10 @@ char buf[1024]; PyOS_snprintf( buf, sizeof(buf), - "", - (unsigned long)(s->e.ident), s->e.filter, s->e.flags, - s->e.fflags, (long)(s->e.data), s->e.udata); + "", + (size_t)(s->e.ident), s->e.filter, s->e.flags, + s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata); return PyString_FromString(buf); } @@ -1230,17 +1254,23 @@ PyObject *pfd; static char *kwlist[] = {"ident", "filter", "flags", "fflags", "data", "udata", NULL}; + static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, &pfd, &(self->e.filter), &(self->e.flags), &(self->e.fflags), &(self->e.data), &(self->e.udata))) { return -1; } - self->e.ident = PyObject_AsFileDescriptor(pfd); - if (self->e.ident == -1) { + if (PyLong_Check(pfd)) { + self->e.ident = PyLong_AsUintptr_t(pfd); + } + else { + self->e.ident = PyObject_AsFileDescriptor(pfd); + } + if (PyErr_Occurred()) { return -1; } return 0; @@ -1250,7 +1280,7 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, int op) { - int result = 0; + Py_intptr_t result = 0; if (!kqueue_event_Check(o)) { if (op == Py_EQ || op == Py_NE) { @@ -1293,7 +1323,7 @@ result = (result > 0); break; } - return PyBool_FromLong(result); + return PyBool_FromLong((long)result); } static PyTypeObject kqueue_event_Type = { From python-checkins at python.org Wed Nov 4 21:31:00 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 20:31:00 -0000 Subject: [Python-checkins] r76109 - in sandbox/trunk/newgil: Doc/library/datetime.rst Lib/distutils/tests/test_build_py.py Lib/distutils/tests/test_util.py Lib/getpass.py Lib/lib2to3/Grammar.txt Lib/lib2to3/fixes/fix_idioms.py Lib/lib2to3/fixes/fix_map.py Lib/lib2to3/fixes/fix_tuple_params.py Lib/lib2to3/pgen2/pgen.py Lib/lib2to3/pgen2/tokenize.py Lib/lib2to3/pytree.py Lib/lib2to3/tests/test_all_fixers.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_parser.py Lib/mailbox.py Lib/test/support.py Lib/test/test_bytes.py Lib/test/test_itertools.py Lib/test/test_mailbox.py Lib/test/test_multibytecodec_support.py Lib/test/test_normalization.py Lib/test/test_shutil.py Lib/test/test_site.py Lib/test/test_wsgiref.py Lib/test/test_xmlrpc_net.py Misc/NEWS Modules/itertoolsmodule.c Modules/termios.c configure configure.in Message-ID: Author: antoine.pitrou Date: Wed Nov 4 21:30:59 2009 New Revision: 76109 Log: Merged revisions 76010,76013,76017,76020,76026,76030-76032,76036,76040,76043,76048,76055,76063,76068,76072,76076,76084,76088,76090,76094,76097,76103 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76010 | antoine.pitrou | 2009-11-01 16:59:11 +0100 (dim., 01 nov. 2009) | 3 lines Fix test skipping in multibyte codec tests ................ r76013 | antoine.pitrou | 2009-11-01 17:13:08 +0100 (dim., 01 nov. 2009) | 8 lines Blocked revisions 76012 via svnmerge ........ r76012 | antoine.pitrou | 2009-11-01 17:10:47 +0100 (dim., 01 nov. 2009) | 3 lines Hum, test skipping when the URL isn't reachable hadn't been applied to trunk. ........ ................ r76017 | gregory.p.smith | 2009-11-01 19:42:17 +0100 (dim., 01 nov. 2009) | 18 lines Merged revisions 76000,76016 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76000 | gregory.p.smith | 2009-10-31 14:26:08 -0700 (Sat, 31 Oct 2009) | 7 lines Fixes issue7208 - getpass would still allow the password to be echoed on Solaris due to not flushing the input buffer. This change also incorporates some additional getpass implementation suggestions for security based on an analysis of getpass.c linked to from the issue. ........ r76016 | gregory.p.smith | 2009-11-01 10:33:55 -0800 (Sun, 01 Nov 2009) | 2 lines news entry for r76000 ........ ................ r76020 | gregory.p.smith | 2009-11-01 20:24:18 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 75999 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75999 | gregory.p.smith | 2009-10-31 14:23:39 -0700 (Sat, 31 Oct 2009) | 2 lines Define TCSASOFT if the flag exists. ........ ................ r76026 | raymond.hettinger | 2009-11-01 21:55:33 +0100 (dim., 01 nov. 2009) | 1 line Fix exception handling in itertools.izip_longest(). ................ r76030 | gregory.p.smith | 2009-11-01 22:09:10 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76028 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76028 | gregory.p.smith | 2009-11-01 13:02:52 -0800 (Sun, 01 Nov 2009) | 2 lines issue1115: convert some AC_TRY_RUNs into AC_TRY_COMPILEs. ........ ................ r76031 | gregory.p.smith | 2009-11-01 22:10:57 +0100 (dim., 01 nov. 2009) | 2 lines block r76029 ................ r76032 | gregory.p.smith | 2009-11-01 22:11:36 +0100 (dim., 01 nov. 2009) | 2 lines generated from r76030 ................ r76036 | antoine.pitrou | 2009-11-01 22:43:20 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76033 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76033 | antoine.pitrou | 2009-11-01 22:26:14 +0100 (dim., 01 nov. 2009) | 3 lines test_normalization should skip and not crash when the resource isn't available ........ ................ r76040 | antoine.pitrou | 2009-11-01 23:13:48 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76037 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76037 | antoine.pitrou | 2009-11-01 23:02:03 +0100 (dim., 01 nov. 2009) | 3 lines Use a custom timeout in test_support.open_urlresource. ........ ................ r76043 | tarek.ziade | 2009-11-01 23:38:44 +0100 (dim., 01 nov. 2009) | 9 lines Merged revisions 76042 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76042 | tarek.ziade | 2009-11-01 23:33:45 +0100 (Sun, 01 Nov 2009) | 1 line fixed stdout alteration in test_distutils ........ ................ r76048 | antoine.pitrou | 2009-11-02 00:55:40 +0100 (lun., 02 nov. 2009) | 9 lines Merged revisions 76047 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76047 | antoine.pitrou | 2009-11-02 00:54:20 +0100 (lun., 02 nov. 2009) | 3 lines Fix and improve some assertions in test_site ........ ................ r76055 | antoine.pitrou | 2009-11-02 12:36:51 +0100 (lun., 02 nov. 2009) | 13 lines Merged revisions 76034,76054 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76034 | antoine.pitrou | 2009-11-01 22:29:33 +0100 (dim., 01 nov. 2009) | 3 lines This should finally fix #6896. Let's watch the buildbots. ........ r76054 | antoine.pitrou | 2009-11-02 12:34:27 +0100 (lun., 02 nov. 2009) | 3 lines Since r76034 was successful, add a NEWS entry for it. ........ ................ r76063 | benjamin.peterson | 2009-11-02 19:16:28 +0100 (lun., 02 nov. 2009) | 77 lines Merged revisions 76062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76062 | benjamin.peterson | 2009-11-02 12:12:12 -0600 (Mon, 02 Nov 2009) | 70 lines Merged revisions 74359,75081,75088,75213,75278,75303,75427-75428,75734-75736,75865,76059-76061 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r74359 | benjamin.peterson | 2009-08-12 17:23:13 -0500 (Wed, 12 Aug 2009) | 1 line don't pass the deprecated print_function option ........ r75081 | benjamin.peterson | 2009-09-26 22:02:57 -0500 (Sat, 26 Sep 2009) | 1 line let 2to3 work with extended iterable unpacking ........ r75088 | benjamin.peterson | 2009-09-27 11:25:21 -0500 (Sun, 27 Sep 2009) | 1 line look on the type only for __call__ ........ r75213 | benjamin.peterson | 2009-10-03 10:09:46 -0500 (Sat, 03 Oct 2009) | 5 lines revert 75212; it's not correct People can use isinstance(x, collections.Callable) if they expect objects with __call__ in their instance dictionaries. ........ r75278 | benjamin.peterson | 2009-10-07 16:25:56 -0500 (Wed, 07 Oct 2009) | 4 lines fix whitespace problems with fix_idioms #3563 Patch by Joe Amenta. ........ r75303 | benjamin.peterson | 2009-10-09 16:59:11 -0500 (Fri, 09 Oct 2009) | 1 line port latin-1 and utf-8 cookie improvements ........ r75427 | benjamin.peterson | 2009-10-14 20:35:57 -0500 (Wed, 14 Oct 2009) | 1 line force floor division ........ r75428 | benjamin.peterson | 2009-10-14 20:39:21 -0500 (Wed, 14 Oct 2009) | 1 line silence -3 warnings about __hash__ ........ r75734 | benjamin.peterson | 2009-10-26 16:25:53 -0500 (Mon, 26 Oct 2009) | 2 lines warn on map(None, ...) with more than 2 arguments #7203 ........ r75735 | benjamin.peterson | 2009-10-26 16:28:25 -0500 (Mon, 26 Oct 2009) | 1 line remove unused result ........ r75736 | benjamin.peterson | 2009-10-26 16:29:02 -0500 (Mon, 26 Oct 2009) | 1 line using get() here is a bit pointless ........ r75865 | benjamin.peterson | 2009-10-27 15:49:00 -0500 (Tue, 27 Oct 2009) | 1 line explain reason for warning ........ r76059 | benjamin.peterson | 2009-11-02 11:43:47 -0600 (Mon, 02 Nov 2009) | 1 line tuples are no longer used for children ........ r76060 | benjamin.peterson | 2009-11-02 11:55:40 -0600 (Mon, 02 Nov 2009) | 1 line revert r76059; apparently some fixers rely on Leaf no () for children ........ r76061 | benjamin.peterson | 2009-11-02 12:06:17 -0600 (Mon, 02 Nov 2009) | 1 line make fix_tuple_params keep the tree valid #7253 ........ ................ ................ r76068 | benjamin.peterson | 2009-11-02 19:30:48 +0100 (lun., 02 nov. 2009) | 24 lines Merged revisions 76064,76066-76067 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76064 | benjamin.peterson | 2009-11-02 12:16:36 -0600 (Mon, 02 Nov 2009) | 1 line add space ................ r76066 | benjamin.peterson | 2009-11-02 12:22:53 -0600 (Mon, 02 Nov 2009) | 9 lines Merged revisions 76065 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76065 | benjamin.peterson | 2009-11-02 12:21:25 -0600 (Mon, 02 Nov 2009) | 1 line don't print stuff in tests ........ ................ r76067 | benjamin.peterson | 2009-11-02 12:24:57 -0600 (Mon, 02 Nov 2009) | 1 line enable test_parser in lib2to3 ................ ................ r76072 | antoine.pitrou | 2009-11-02 21:57:43 +0100 (lun., 02 nov. 2009) | 9 lines Blocked revisions 76071 via svnmerge ........ r76071 | antoine.pitrou | 2009-11-02 21:47:33 +0100 (lun., 02 nov. 2009) | 4 lines Add acceptance of long ints to test_memoryio.py (in preparation for fix of #7249 in 2.6) ........ ................ r76076 | skip.montanaro | 2009-11-03 03:44:04 +0100 (mar., 03 nov. 2009) | 1 line typo (space-o?) ................ r76084 | mark.dickinson | 2009-11-03 17:29:10 +0100 (mar., 03 nov. 2009) | 9 lines Merged revisions 76082 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76082 | mark.dickinson | 2009-11-03 16:26:14 +0000 (Tue, 03 Nov 2009) | 1 line Fix doc typo reported by Arfrever. ........ ................ r76088 | antoine.pitrou | 2009-11-03 18:13:59 +0100 (mar., 03 nov. 2009) | 3 lines Since time.xmlrpc.com is unreliable, add another test to test_xmlrpc_net ................ r76090 | antoine.pitrou | 2009-11-03 18:20:10 +0100 (mar., 03 nov. 2009) | 9 lines Merged revisions 76086 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76086 | antoine.pitrou | 2009-11-03 17:41:20 +0100 (mar., 03 nov. 2009) | 3 lines Try to make test_wsgiref less fragile against environment changes by other tests ........ ................ r76094 | georg.brandl | 2009-11-03 19:24:38 +0100 (mar., 03 nov. 2009) | 9 lines Recorded merge of revisions 76075 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76075 | skip.montanaro | 2009-11-03 02:43:59 +0000 (Di, 03 Nov 2009) | 1 line typo (space-o?) ........ ................ r76097 | georg.brandl | 2009-11-03 19:35:33 +0100 (mar., 03 nov. 2009) | 8 lines Blocked revisions 76095 via svnmerge ........ r76095 | georg.brandl | 2009-11-03 18:34:27 +0000 (Di, 03 Nov 2009) | 1 line #7256: add versionadded tags for functions copied from cgi. ........ ................ r76103 | antoine.pitrou | 2009-11-04 01:57:15 +0100 (mer., 04 nov. 2009) | 9 lines Merged revisions 76101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76101 | antoine.pitrou | 2009-11-04 01:50:26 +0100 (mer., 04 nov. 2009) | 3 lines Make test_shutil clean up after itself ........ ................ Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Doc/library/datetime.rst sandbox/trunk/newgil/Lib/distutils/tests/test_build_py.py sandbox/trunk/newgil/Lib/distutils/tests/test_util.py sandbox/trunk/newgil/Lib/getpass.py sandbox/trunk/newgil/Lib/lib2to3/Grammar.txt sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_idioms.py sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_map.py sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_tuple_params.py sandbox/trunk/newgil/Lib/lib2to3/pgen2/pgen.py sandbox/trunk/newgil/Lib/lib2to3/pgen2/tokenize.py sandbox/trunk/newgil/Lib/lib2to3/pytree.py sandbox/trunk/newgil/Lib/lib2to3/tests/test_all_fixers.py sandbox/trunk/newgil/Lib/lib2to3/tests/test_fixers.py sandbox/trunk/newgil/Lib/lib2to3/tests/test_parser.py sandbox/trunk/newgil/Lib/mailbox.py sandbox/trunk/newgil/Lib/test/support.py sandbox/trunk/newgil/Lib/test/test_bytes.py sandbox/trunk/newgil/Lib/test/test_itertools.py sandbox/trunk/newgil/Lib/test/test_mailbox.py sandbox/trunk/newgil/Lib/test/test_multibytecodec_support.py sandbox/trunk/newgil/Lib/test/test_normalization.py sandbox/trunk/newgil/Lib/test/test_shutil.py sandbox/trunk/newgil/Lib/test/test_site.py sandbox/trunk/newgil/Lib/test/test_wsgiref.py sandbox/trunk/newgil/Lib/test/test_xmlrpc_net.py sandbox/trunk/newgil/Misc/NEWS sandbox/trunk/newgil/Modules/itertoolsmodule.c sandbox/trunk/newgil/Modules/termios.c sandbox/trunk/newgil/configure sandbox/trunk/newgil/configure.in Modified: sandbox/trunk/newgil/Doc/library/datetime.rst ============================================================================== --- sandbox/trunk/newgil/Doc/library/datetime.rst (original) +++ sandbox/trunk/newgil/Doc/library/datetime.rst Wed Nov 4 21:30:59 2009 @@ -469,7 +469,8 @@ Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/ vgent/calendar/isocalendar.htm for a good explanation. + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first Modified: sandbox/trunk/newgil/Lib/distutils/tests/test_build_py.py ============================================================================== --- sandbox/trunk/newgil/Lib/distutils/tests/test_build_py.py (original) +++ sandbox/trunk/newgil/Lib/distutils/tests/test_build_py.py Wed Nov 4 21:30:59 2009 @@ -69,6 +69,7 @@ open(os.path.join(testdir, "testfile"), "w").close() os.chdir(sources) + old_stdout = sys.stdout sys.stdout = io.StringIO() try: @@ -87,7 +88,7 @@ finally: # Restore state. os.chdir(cwd) - sys.stdout = sys.__stdout__ + sys.stdout = old_stdout def test_dont_write_bytecode(self): # makes sure byte_compile is not used Modified: sandbox/trunk/newgil/Lib/distutils/tests/test_util.py ============================================================================== --- sandbox/trunk/newgil/Lib/distutils/tests/test_util.py (original) +++ sandbox/trunk/newgil/Lib/distutils/tests/test_util.py Wed Nov 4 21:30:59 2009 @@ -60,6 +60,8 @@ util.find_executable = self._find_executable self._exes = {} self.old_popen = subprocess.Popen + self.old_stdout = sys.stdout + self.old_stderr = sys.stderr FakePopen.test_class = self subprocess.Popen = FakePopen @@ -79,6 +81,8 @@ sysconfig._config_vars = copy(self._config_vars) util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen + sys.old_stdout = self.old_stdout + sys.old_stderr = self.old_stderr super(UtilTestCase, self).tearDown() def _set_uname(self, uname): Modified: sandbox/trunk/newgil/Lib/getpass.py ============================================================================== --- sandbox/trunk/newgil/Lib/getpass.py (original) +++ sandbox/trunk/newgil/Lib/getpass.py Wed Nov 4 21:30:59 2009 @@ -62,12 +62,16 @@ try: old = termios.tcgetattr(fd) # a copy to save new = old[:] - new[3] &= ~termios.ECHO # 3 == 'lflags' + new[3] &= ~(termios.ECHO|termios.ISIG) # 3 == 'lflags' + tcsetattr_flags = termios.TCSAFLUSH + if hasattr(termios, 'TCSASOFT'): + tcsetattr_flags |= termios.TCSASOFT try: - termios.tcsetattr(fd, termios.TCSADRAIN, new) + termios.tcsetattr(fd, tcsetattr_flags, new) passwd = _raw_input(prompt, stream, input=input) finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old) + termios.tcsetattr(fd, tcsetattr_flags, old) + stream.flush() # issue7208 except termios.error as e: if passwd is not None: # _raw_input succeeded. The final tcsetattr failed. Reraise @@ -124,6 +128,7 @@ if prompt: stream.write(prompt) stream.flush() + # NOTE: The Python C API calls flockfile() (and unlock) during readline. line = input.readline() if not line: raise EOFError Modified: sandbox/trunk/newgil/Lib/lib2to3/Grammar.txt ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/Grammar.txt (original) +++ sandbox/trunk/newgil/Lib/lib2to3/Grammar.txt Wed Nov 4 21:30:59 2009 @@ -53,8 +53,9 @@ simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt) -expr_stmt: testlist (augassign (yield_expr|testlist) | - ('=' (yield_expr|testlist))*) +expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist_star_expr))*) +testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter @@ -112,6 +113,7 @@ not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +star_expr: '*' expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* @@ -125,14 +127,14 @@ '{' [dictsetmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+ | '.' '.' '.') -listmaker: test ( comp_for | (',' test)* [','] ) -testlist_gexp: test ( comp_for | (',' test)* [','] ) +listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_gexp: test ( comp_for | (',' (test|star_expr))* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] -exprlist: expr (',' expr)* [','] +exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | (test (comp_for | (',' test)* [','])) ) Modified: sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_idioms.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_idioms.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_idioms.py Wed Nov 4 21:30:59 2009 @@ -29,7 +29,7 @@ # Local imports from .. import fixer_base -from ..fixer_util import Call, Comma, Name, Node, syms +from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" TYPE = "power< 'type' trailer< '(' x=any ')' > >" @@ -130,5 +130,24 @@ else: raise RuntimeError("should not have reached here") sort_stmt.remove() - if next_stmt: - next_stmt[0].prefix = sort_stmt.prefix + + btwn = sort_stmt.prefix + # Keep any prefix lines between the sort_stmt and the list_call and + # shove them right after the sorted() call. + if "\n" in btwn: + if next_stmt: + # The new prefix should be everything from the sort_stmt's + # prefix up to the last newline, then the old prefix after a new + # line. + prefix_lines = (btwn.rpartition("\n")[0], next_stmt[0].prefix) + next_stmt[0].prefix = "\n".join(prefix_lines) + else: + assert list_call.parent + assert list_call.next_sibling is None + # Put a blank line after list_call and set its prefix. + end_line = BlankLine() + list_call.parent.append_child(end_line) + assert list_call.next_sibling is end_line + # The new prefix should be everything up to the first new line + # of sort_stmt's prefix. + end_line.prefix = btwn.rpartition("\n")[0] Modified: sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_map.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_map.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_map.py Wed Nov 4 21:30:59 2009 @@ -49,8 +49,7 @@ > | power< - 'map' - args=trailer< '(' [any] ')' > + 'map' trailer< '(' [arglist=any] ')' > > """ @@ -66,13 +65,22 @@ new.prefix = "" new = Call(Name("list"), [new]) elif "map_lambda" in results: - new = ListComp(results.get("xp").clone(), - results.get("fp").clone(), - results.get("it").clone()) + new = ListComp(results["xp"].clone(), + results["fp"].clone(), + results["it"].clone()) else: if "map_none" in results: new = results["arg"].clone() else: + if "arglist" in results: + args = results["arglist"] + if args.type == syms.arglist and \ + args.children[0].type == token.NAME and \ + args.children[0].value == "None": + self.warning(node, "cannot convert map(None, ...) " + "with multiple arguments because map() " + "now truncates to the shortest sequence") + return if in_special_context(node): return None new = node.clone() Modified: sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_tuple_params.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_tuple_params.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/fixes/fix_tuple_params.py Wed Nov 4 21:30:59 2009 @@ -96,6 +96,8 @@ new_lines[0].prefix = indent after = start + 1 + for line in new_lines: + line.parent = suite[0] suite[0].children[after:after] = new_lines for i in range(after+1, after+len(new_lines)+1): suite[0].children[i].prefix = indent Modified: sandbox/trunk/newgil/Lib/lib2to3/pgen2/pgen.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/pgen2/pgen.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/pgen2/pgen.py Wed Nov 4 21:30:59 2009 @@ -379,6 +379,8 @@ return False return True + __hash__ = None # For Py3 compatibility. + def generate_grammar(filename="Grammar.txt"): p = ParserGenerator(filename) return p.make_grammar() Modified: sandbox/trunk/newgil/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/pgen2/tokenize.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/pgen2/tokenize.py Wed Nov 4 21:30:59 2009 @@ -231,6 +231,17 @@ cookie_re = re.compile("coding[:=]\s*([-\w.]+)") +def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + def detect_encoding(readline): """ The detect_encoding() function is used to detect the encoding that should @@ -265,7 +276,7 @@ matches = cookie_re.findall(line_string) if not matches: return None - encoding = matches[0] + encoding = _get_normal_name(matches[0]) try: codec = lookup(encoding) except LookupError: @@ -375,7 +386,7 @@ column = 0 while pos < max: # measure leading whitespace if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize + elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize elif line[pos] == '\f': column = 0 else: break pos = pos + 1 Modified: sandbox/trunk/newgil/Lib/lib2to3/pytree.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/pytree.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/pytree.py Wed Nov 4 21:30:59 2009 @@ -63,6 +63,8 @@ return NotImplemented return self._eq(other) + __hash__ = None # For Py3 compatibility. + def __ne__(self, other): """ Compare two nodes for inequality. Modified: sandbox/trunk/newgil/Lib/lib2to3/tests/test_all_fixers.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/tests/test_all_fixers.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/tests/test_all_fixers.py Wed Nov 4 21:30:59 2009 @@ -16,10 +16,8 @@ class Test_all(support.TestCase): def setUp(self): - options = {"print_function" : False} - self.refactor = support.get_refactorer(options=options) + self.refactor = support.get_refactorer() def test_all_project_files(self): for filepath in support.all_project_files(): - print("Fixing %s..." % filepath) self.refactor.refactor_file(filepath) Modified: sandbox/trunk/newgil/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/tests/test_fixers.py Wed Nov 4 21:30:59 2009 @@ -339,6 +339,12 @@ a = "from functools import reduce\nreduce(a, b, c)" self.check(b, a) + def test_bug_7253(self): + # fix_tuple_params was being bad and orphaning nodes in the tree. + b = "def x(arg): reduce(sum, [])" + a = "from functools import reduce\ndef x(arg): reduce(sum, [])" + self.check(b, a) + def test_call_with_lambda(self): b = "reduce(lambda x, y: x + y, seq)" a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" @@ -2834,6 +2840,11 @@ a = """x = list(map(f, 'abc')) # foo""" self.check(b, a) + def test_None_with_multiple_arguments(self): + s = """x = map(None, a, b, c)""" + self.warns_unchanged(s, "cannot convert map(None, ...) with " + "multiple arguments") + def test_map_basic(self): b = """x = map(f, 'abc')""" a = """x = list(map(f, 'abc'))""" @@ -2847,10 +2858,6 @@ a = """x = list('abc')""" self.check(b, a) - b = """x = map(None, 'abc', 'def')""" - a = """x = list(map(None, 'abc', 'def'))""" - self.check(b, a) - b = """x = map(lambda x: x+1, range(4))""" a = """x = [x+1 for x in range(4)]""" self.check(b, a) @@ -3238,6 +3245,46 @@ """ self.check(b, a) + b = r""" + try: + m = list(s) + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + except: pass + """ + self.check(b, a) + + b = r""" + try: + m = list(s) + # foo + m.sort() + except: pass + """ + + a = r""" + try: + m = sorted(s) + # foo + except: pass + """ + self.check(b, a) + + b = r""" + m = list(s) + # more comments + m.sort()""" + + a = r""" + m = sorted(s) + # more comments""" + self.check(b, a) + def test_sort_simple_expr(self): b = """ v = t Modified: sandbox/trunk/newgil/Lib/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/newgil/Lib/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/newgil/Lib/lib2to3/tests/test_parser.py Wed Nov 4 21:30:59 2009 @@ -147,7 +147,6 @@ def test_all_project_files(self): for filepath in support.all_project_files(): - print("Parsing %s..." % filepath) with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] fp.seek(0) @@ -161,6 +160,11 @@ if diff(filepath, new): self.fail("Idempotency failed: %s" % filepath) + def test_extended_unpacking(self): + driver.parse_string("a, *b, c = x\n") + driver.parse_string("[*a, b] = x\n") + driver.parse_string("(z, *y, w) = m\n") + driver.parse_string("for *z, m in d: pass\n") class TestLiterals(GrammarTest): Modified: sandbox/trunk/newgil/Lib/mailbox.py ============================================================================== --- sandbox/trunk/newgil/Lib/mailbox.py (original) +++ sandbox/trunk/newgil/Lib/mailbox.py Wed Nov 4 21:30:59 2009 @@ -234,6 +234,9 @@ raise NoSuchMailboxError(self._path) self._toc = {} self._last_read = None # Records last time we read cur/new + # NOTE: we manually invalidate _last_read each time we do any + # modifications ourselves, otherwise we might get tripped up by + # bogus mtime behaviour on some systems (see issue #6896). def add(self, message): """Add message and return assigned key.""" @@ -267,11 +270,15 @@ raise if isinstance(message, MaildirMessage): os.utime(dest, (os.path.getatime(dest), message.get_date())) + # Invalidate cached toc + self._last_read = None return uniq def remove(self, key): """Remove the keyed message; raise KeyError if it doesn't exist.""" os.remove(os.path.join(self._path, self._lookup(key))) + # Invalidate cached toc (only on success) + self._last_read = None def discard(self, key): """If the keyed message exists, remove it.""" @@ -306,6 +313,8 @@ if isinstance(message, MaildirMessage): os.utime(new_path, (os.path.getatime(new_path), message.get_date())) + # Invalidate cached toc + self._last_read = None def get_message(self, key): """Return a Message representation or raise a KeyError.""" @@ -360,7 +369,9 @@ def flush(self): """Write any pending changes to disk.""" - return # Maildir changes are always written immediately. + # Maildir changes are always written immediately, so there's nothing + # to do except invalidate our cached toc. + self._last_read = None def lock(self): """Lock the mailbox.""" Modified: sandbox/trunk/newgil/Lib/test/support.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/support.py (original) +++ sandbox/trunk/newgil/Lib/test/support.py Wed Nov 4 21:30:59 2009 @@ -458,10 +458,17 @@ return open(fn, *args, **kw) print('\tfetching %s ...' % url, file=get_original_stdout()) - fn, _ = urllib.request.urlretrieve(url, fn) + f = urllib.request.urlopen(url, timeout=15) + try: + with open(fn, "wb") as out: + s = f.read() + while s: + out.write(s) + s = f.read() + finally: + f.close() return open(fn, *args, **kw) - class WarningsRecorder(object): """Convenience wrapper for the warnings list returned on entry to the warnings.catch_warnings() context manager. Modified: sandbox/trunk/newgil/Lib/test/test_bytes.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_bytes.py (original) +++ sandbox/trunk/newgil/Lib/test/test_bytes.py Wed Nov 4 21:30:59 2009 @@ -935,7 +935,7 @@ self.assertRaises(BytesWarning, operator.eq, bytearray(b''), '') self.assertRaises(BytesWarning, operator.ne, bytearray(b''), '') else: - # raise test.support.TestSkipped("BytesWarning is needed for this test: use -bb option") + # self.skipTest("BytesWarning is needed for this test: use -bb option") pass # Optimizations: Modified: sandbox/trunk/newgil/Lib/test/test_itertools.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_itertools.py (original) +++ sandbox/trunk/newgil/Lib/test/test_itertools.py Wed Nov 4 21:30:59 2009 @@ -581,6 +581,46 @@ ids = list(map(id, list(zip_longest('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_bug_7244(self): + + class Repeater: + # this class is similar to itertools.repeat + def __init__(self, o, t, e): + self.o = o + self.t = int(t) + self.e = e + def __iter__(self): # its iterator is itself + return self + def __next__(self): + if self.t > 0: + self.t -= 1 + return self.o + else: + raise self.e + + # Formerly this code in would fail in debug mode + # with Undetected Error and Stop Iteration + r1 = Repeater(1, 3, StopIteration) + r2 = Repeater(2, 4, StopIteration) + def run(r1, r2): + result = [] + for i, j in zip_longest(r1, r2, fillvalue=0): + with support.captured_output('stdout'): + print((i, j)) + result.append((i, j)) + return result + self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)]) + + # Formerly, the RuntimeError would be lost + # and StopIteration would stop as expected + r1 = Repeater(1, 3, RuntimeError) + r2 = Repeater(2, 4, StopIteration) + it = zip_longest(r1, r2, fillvalue=0) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertEqual(next(it), (1, 2)) + self.assertRaises(RuntimeError, next, it) + def test_product(self): for args, result in [ ([], [()]), # zero iterables Modified: sandbox/trunk/newgil/Lib/test/test_mailbox.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_mailbox.py (original) +++ sandbox/trunk/newgil/Lib/test/test_mailbox.py Wed Nov 4 21:30:59 2009 @@ -673,6 +673,9 @@ self.assertEqual(self._box._lookup(key0), os.path.join('new', key0)) os.remove(os.path.join(self._path, 'new', key0)) self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)}) + # Be sure that the TOC is read back from disk (see issue #6896 + # about bad mtime behaviour on some systems). + self._box.flush() self.assertRaises(KeyError, lambda: self._box._lookup(key0)) self.assertEqual(self._box._toc, {}) Modified: sandbox/trunk/newgil/Lib/test/test_multibytecodec_support.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_multibytecodec_support.py (original) +++ sandbox/trunk/newgil/Lib/test/test_multibytecodec_support.py Wed Nov 4 21:30:59 2009 @@ -279,7 +279,7 @@ try: self.open_mapping_file() # test it to report the error early except IOError: - raise support.TestSkipped("Could not retrieve "+self.mapfileurl) + self.skipTest("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): return support.open_urlresource(self.mapfileurl) Modified: sandbox/trunk/newgil/Lib/test/test_normalization.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_normalization.py (original) +++ sandbox/trunk/newgil/Lib/test/test_normalization.py Wed Nov 4 21:30:59 2009 @@ -42,6 +42,11 @@ class NormalizationTest(unittest.TestCase): def test_main(self): part1_data = {} + # Hit the exception early + try: + open_urlresource(TESTDATAURL, encoding="utf-8") + except IOError: + self.skipTest("Could not retrieve " + TESTDATAURL) for line in open_urlresource(TESTDATAURL, encoding="utf-8"): if '#' in line: line = line.split('#')[0] @@ -97,8 +102,6 @@ def test_main(): - # Skip the test early if the 'urlfetch' resource is not enabled. - open_urlresource(TESTDATAURL) run_unittest(NormalizationTest) if __name__ == "__main__": Modified: sandbox/trunk/newgil/Lib/test/test_shutil.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_shutil.py (original) +++ sandbox/trunk/newgil/Lib/test/test_shutil.py Wed Nov 4 21:30:59 2009 @@ -118,7 +118,7 @@ if os.path.exists(path): os.remove(path) for path in (src_dir, - os.path.abspath(os.path.join(dst_dir, os.path.pardir)) + os.path.dirname(dst_dir) ): if os.path.exists(path): shutil.rmtree(path) @@ -140,65 +140,69 @@ join = os.path.join exists = os.path.exists src_dir = tempfile.mkdtemp() - dst_dir = join(tempfile.mkdtemp(), 'destination') - write_data(join(src_dir, 'test.txt'), '123') - write_data(join(src_dir, 'test.tmp'), '123') - os.mkdir(join(src_dir, 'test_dir')) - write_data(join(src_dir, 'test_dir', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2')) - write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') - os.mkdir(join(src_dir, 'test_dir2', 'subdir')) - os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) - write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') - write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') + try: + dst_dir = join(tempfile.mkdtemp(), 'destination') + write_data(join(src_dir, 'test.txt'), '123') + write_data(join(src_dir, 'test.tmp'), '123') + os.mkdir(join(src_dir, 'test_dir')) + write_data(join(src_dir, 'test_dir', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2')) + write_data(join(src_dir, 'test_dir2', 'test.txt'), '456') + os.mkdir(join(src_dir, 'test_dir2', 'subdir')) + os.mkdir(join(src_dir, 'test_dir2', 'subdir2')) + write_data(join(src_dir, 'test_dir2', 'subdir', 'test.txt'), '456') + write_data(join(src_dir, 'test_dir2', 'subdir2', 'test.py'), '456') - # testing glob-like patterns - try: - patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(exists(join(dst_dir, 'test.txt'))) - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) - try: - patterns = shutil.ignore_patterns('*.tmp', 'subdir*') - shutil.copytree(src_dir, dst_dir, ignore=patterns) - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) - finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + # testing glob-like patterns + try: + patterns = shutil.ignore_patterns('*.tmp', 'test_dir2') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(exists(join(dst_dir, 'test.txt'))) + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) + try: + patterns = shutil.ignore_patterns('*.tmp', 'subdir*') + shutil.copytree(src_dir, dst_dir, ignore=patterns) + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test.tmp'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) - # testing callable-style - try: - def _filter(src, names): - res = [] - for name in names: - path = os.path.join(src, name) - - if (os.path.isdir(path) and - path.split()[-1] == 'subdir'): - res.append(name) - elif os.path.splitext(path)[-1] in ('.py'): - res.append(name) - return res - - shutil.copytree(src_dir, dst_dir, ignore=_filter) - - # checking the result: some elements should not be copied - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', - 'test.py'))) - self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + # testing callable-style + try: + def _filter(src, names): + res = [] + for name in names: + path = os.path.join(src, name) + + if (os.path.isdir(path) and + path.split()[-1] == 'subdir'): + res.append(name) + elif os.path.splitext(path)[-1] in ('.py'): + res.append(name) + return res + + shutil.copytree(src_dir, dst_dir, ignore=_filter) + + # checking the result: some elements should not be copied + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir2', + 'test.py'))) + self.assertTrue(not exists(join(dst_dir, 'test_dir2', 'subdir'))) + finally: + if os.path.exists(dst_dir): + shutil.rmtree(dst_dir) finally: - if os.path.exists(dst_dir): - shutil.rmtree(dst_dir) + shutil.rmtree(src_dir) + shutil.rmtree(os.path.dirname(dst_dir)) if hasattr(os, "symlink"): def test_dont_copy_file_onto_link_to_itself(self): Modified: sandbox/trunk/newgil/Lib/test/test_site.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_site.py (original) +++ sandbox/trunk/newgil/Lib/test/test_site.py Wed Nov 4 21:30:59 2009 @@ -70,9 +70,9 @@ def pth_file_tests(self, pth_file): """Contain common code for testing results of reading a .pth file""" self.assertTrue(pth_file.imported in sys.modules, - "%s not in sys.path" % pth_file.imported) - self.assertTrue(site.makepath(pth_file.good_dir_path)[0] in sys.path) - self.assertTrue(not os.path.exists(pth_file.bad_dir_path)) + "%s not in sys.modules" % pth_file.imported) + self.assertIn(site.makepath(pth_file.good_dir_path)[0], sys.path) + self.assertFalse(os.path.exists(pth_file.bad_dir_path)) def test_addpackage(self): # Make sure addpackage() imports if the line starts with 'import', @@ -104,7 +104,7 @@ def test_s_option(self): usersite = site.USER_SITE - self.assertTrue(usersite in sys.path) + self.assertIn(usersite, sys.path) rc = subprocess.call([sys.executable, '-c', 'import sys; sys.exit(%r in sys.path)' % usersite]) @@ -139,7 +139,8 @@ site.USER_BASE = None with EnvironmentVarGuard() as environ: environ['PYTHONUSERBASE'] = 'xoxo' - self.assertTrue(site.getuserbase().startswith('xoxo')) + self.assertTrue(site.getuserbase().startswith('xoxo'), + site.getuserbase()) def test_getusersitepackages(self): site.USER_SITE = None @@ -148,14 +149,14 @@ # the call sets USER_BASE *and* USER_SITE self.assertEquals(site.USER_SITE, user_site) - self.assertTrue(user_site.startswith(site.USER_BASE)) + self.assertTrue(user_site.startswith(site.USER_BASE), user_site) def test_getsitepackages(self): site.PREFIXES = ['xoxo'] dirs = site.getsitepackages() if sys.platform in ('os2emx', 'riscos'): - self.assertTrue(len(dirs), 1) + self.assertEqual(len(dirs), 1) wanted = os.path.join('xoxo', 'Lib', 'site-packages') self.assertEquals(dirs[0], wanted) elif os.sep == '/': @@ -175,7 +176,7 @@ if sys.platform == "darwin": site.PREFIXES = ['Python.framework'] dirs = site.getsitepackages() - self.assertTrue(len(dirs), 4) + self.assertEqual(len(dirs), 4) wanted = os.path.join('~', 'Library', 'Python', sys.version[:3], 'site-packages') self.assertEquals(dirs[2], os.path.expanduser(wanted)) Modified: sandbox/trunk/newgil/Lib/test/test_wsgiref.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_wsgiref.py (original) +++ sandbox/trunk/newgil/Lib/test/test_wsgiref.py Wed Nov 4 21:30:59 2009 @@ -9,7 +9,9 @@ from wsgiref.simple_server import make_server from io import StringIO, BytesIO, BufferedReader from socketserver import BaseServer -import re, sys +import os +import re +import sys from test import support @@ -444,6 +446,11 @@ class ErrorHandler(BaseCGIHandler): """Simple handler subclass for testing BaseHandler""" + # BaseHandler records the OS environment at import time, but envvars + # might have been changed later by other tests, which trips up + # HandlerTests.testEnviron(). + os_environ = dict(os.environ.items()) + def __init__(self,**kw): setup_testing_defaults(kw) BaseCGIHandler.__init__( Modified: sandbox/trunk/newgil/Lib/test/test_xmlrpc_net.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_xmlrpc_net.py (original) +++ sandbox/trunk/newgil/Lib/test/test_xmlrpc_net.py Wed Nov 4 21:30:59 2009 @@ -1,5 +1,6 @@ #!/usr/bin/env python +import collections import errno import socket import sys @@ -17,8 +18,7 @@ try: t0 = server.currentTime.getCurrentTime() except socket.error as e: - print(" test_current_time: skipping test, got error: %s" % e, - file=sys.stderr) + self.skipTest("network error: %s" % e) return # Perform a minimal sanity check on the result, just to be sure @@ -35,6 +35,21 @@ # time on the server should not be too big. self.assertTrue(delta.days <= 1) + def test_python_builders(self): + # Get the list of builders from the XMLRPC buildbot interface at + # python.org. + server = xmlrpclib.ServerProxy("http://www.python.org/dev/buildbot/all/xmlrpc/") + try: + builders = server.getAllBuilders() + except socket.error as e: + self.skipTest("network error: %s" % e) + return + + # Perform a minimal sanity check on the result, just to be sure + # the request means what we think it means. + self.assertIsInstance(builders, collections.Sequence) + self.assertTrue([x for x in builders if "trunk" in x], builders) + def test_main(): support.requires("network") Modified: sandbox/trunk/newgil/Misc/NEWS ============================================================================== --- sandbox/trunk/newgil/Misc/NEWS (original) +++ sandbox/trunk/newgil/Misc/NEWS Wed Nov 4 21:30:59 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7244: itertools.izip_longest() no longer ignores exceptions + raised during the formation of an output tuple. + - Issue #3297: On wide unicode builds, do not split unicode characters into surrogates. @@ -120,6 +123,16 @@ Library ------- +- Issue #6896: mailbox.Maildir now invalidates its internal cache each time + a modification is done through it. This fixes inconsistencies and test + failures on systems with slightly bogus mtime behaviour. + +- Issue #7246 & Issue #7208: getpass now properly flushes input before + reading from stdin so that existing input does not confuse it and + lead to incorrect entry or an IOError. It also properly flushes it + afterwards to avoid the terminal echoing the input afterwards on + OSes such as Solaris. + - Issue #7233: Fix a number of two-argument Decimal methods to make sure that they accept an int or long as the second argument. Also fix buggy handling of large arguments (those with coefficient longer Modified: sandbox/trunk/newgil/Modules/itertoolsmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/itertoolsmodule.c (original) +++ sandbox/trunk/newgil/Modules/itertoolsmodule.c Wed Nov 4 21:30:59 2009 @@ -3344,71 +3344,73 @@ static PyObject * zip_longest_next(ziplongestobject *lz) { - Py_ssize_t i; - Py_ssize_t tuplesize = lz->tuplesize; - PyObject *result = lz->result; - PyObject *it; - PyObject *item; - PyObject *olditem; + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; - if (tuplesize == 0) - return NULL; + if (tuplesize == 0) + return NULL; if (lz->numactive == 0) return NULL; - if (Py_REFCNT(result) == 1) { - Py_INCREF(result); - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + if (Py_REFCNT(result) == 1) { + Py_INCREF(result); + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - olditem = PyTuple_GET_ITEM(result, i); - PyTuple_SET_ITEM(result, i, item); - Py_DECREF(olditem); - } - } else { - result = PyTuple_New(tuplesize); - if (result == NULL) - return NULL; - for (i=0 ; i < tuplesize ; i++) { - it = PyTuple_GET_ITEM(lz->ittuple, i); + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); + } + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) + return NULL; + for (i=0 ; i < tuplesize ; i++) { + it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { Py_INCREF(lz->fillvalue); item = lz->fillvalue; } else { - item = (*Py_TYPE(it)->tp_iternext)(it); + item = PyIter_Next(it); if (item == NULL) { - lz->numactive -= 1; - if (lz->numactive == 0) { + lz->numactive -= 1; + if (lz->numactive == 0 || PyErr_Occurred()) { + lz->numactive = 0; Py_DECREF(result); return NULL; } else { Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = lz->fillvalue; PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } } } - PyTuple_SET_ITEM(result, i, item); - } - } - return result; + PyTuple_SET_ITEM(result, i, item); + } + } + return result; } PyDoc_STRVAR(zip_longest_doc, Modified: sandbox/trunk/newgil/Modules/termios.c ============================================================================== --- sandbox/trunk/newgil/Modules/termios.c (original) +++ sandbox/trunk/newgil/Modules/termios.c Wed Nov 4 21:30:59 2009 @@ -355,6 +355,9 @@ {"TCSANOW", TCSANOW}, {"TCSADRAIN", TCSADRAIN}, {"TCSAFLUSH", TCSAFLUSH}, +#ifdef TCSASOFT + {"TCSASOFT", TCSASOFT}, +#endif /* tcflush() constants */ {"TCIFLUSH", TCIFLUSH}, Modified: sandbox/trunk/newgil/configure ============================================================================== --- sandbox/trunk/newgil/configure (original) +++ sandbox/trunk/newgil/configure Wed Nov 4 21:30:59 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 75684 . +# From configure.in Revision: 76030 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -4546,50 +4546,47 @@ if test "${ac_cv_no_strict_aliasing_ok+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test "$cross_compiling" = yes; then - ac_cv_no_strict_aliasing_ok=no -else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_no_strict_aliasing_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_no_strict_aliasing_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_no_strict_aliasing_ok=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi CC="$ac_save_cc" @@ -4743,50 +4740,47 @@ else ac_save_cc="$CC" CC="$CC -OPT:Olimit=0" -if test "$cross_compiling" = yes; then - ac_cv_opt_olimit_ok=no -else - cat >conftest.$ac_ext <<_ACEOF +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_opt_olimit_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_opt_olimit_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_opt_olimit_ok=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CC="$ac_save_cc" fi @@ -4811,50 +4805,47 @@ else ac_save_cc="$CC" CC="$CC -Olimit 1500" - if test "$cross_compiling" = yes; then - ac_cv_olimit_ok=no -else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + +int +main () +{ int main() { return 0; } + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 + (eval "$ac_compile") 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_olimit_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_olimit_ok=no + ac_cv_olimit_ok=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CC="$ac_save_cc" fi Modified: sandbox/trunk/newgil/configure.in ============================================================================== --- sandbox/trunk/newgil/configure.in (original) +++ sandbox/trunk/newgil/configure.in Wed Nov 4 21:30:59 2009 @@ -856,9 +856,8 @@ ac_save_cc="$CC" CC="$CC -fno-strict-aliasing" AC_CACHE_VAL(ac_cv_no_strict_aliasing_ok, - AC_TRY_RUN([int main() { return 0; }], + AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_no_strict_aliasing_ok=yes, - ac_cv_no_strict_aliasing_ok=no, ac_cv_no_strict_aliasing_ok=no)) CC="$ac_save_cc" AC_MSG_RESULT($ac_cv_no_strict_aliasing_ok) @@ -1005,10 +1004,10 @@ AC_CACHE_VAL(ac_cv_opt_olimit_ok, [ac_save_cc="$CC" CC="$CC -OPT:Olimit=0" -AC_TRY_RUN([int main() { return 0; }], +AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_opt_olimit_ok=yes, ac_cv_opt_olimit_ok=no, - ac_cv_opt_olimit_ok=no) + ) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_opt_olimit_ok) if test $ac_cv_opt_olimit_ok = yes; then @@ -1027,10 +1026,10 @@ AC_CACHE_VAL(ac_cv_olimit_ok, [ac_save_cc="$CC" CC="$CC -Olimit 1500" - AC_TRY_RUN([int main() { return 0; }], + AC_TRY_COMPILE([],[int main() { return 0; }], ac_cv_olimit_ok=yes, ac_cv_olimit_ok=no, - ac_cv_olimit_ok=no) + ) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_olimit_ok) if test $ac_cv_olimit_ok = yes; then From python-checkins at python.org Wed Nov 4 22:04:05 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 21:04:05 -0000 Subject: [Python-checkins] r76110 - sandbox/trunk/newgil/Python/ceval_gil.h Message-ID: Author: antoine.pitrou Date: Wed Nov 4 22:04:05 2009 New Revision: 76110 Log: Document the implementation Modified: sandbox/trunk/newgil/Python/ceval_gil.h Modified: sandbox/trunk/newgil/Python/ceval_gil.h ============================================================================== --- sandbox/trunk/newgil/Python/ceval_gil.h (original) +++ sandbox/trunk/newgil/Python/ceval_gil.h Wed Nov 4 22:04:05 2009 @@ -25,6 +25,40 @@ /* #define TRACE_PRIO */ +/* + Notes about the implementation: + + - The GIL is just a boolean variable (gil_locked) whose access is protected + by a mutex, and whose changes are signalled by a condition variable. The + mutex itself is rarely taken and, therefore, mostly uncontended. + + - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be + able to release the GIL on demand by another thread. A volatile boolean + variable (gil_drop_request) is used for that purpose, which is checked + at every turn of the eval loop. + + [Actually, another volatile boolean variable (eval_breaker) is used + which aggregates several conditions into one. Volatile booleans are + ok as signalling means since Python is run on cache-coherent + architectures only.] + + - A thread wanting to take the GIL will first wait for a given amount of + time before setting gil_drop_request. This amount of time defines the + ideal thread switching period. It is available for the user to read + and modify using `sys.{get,set}switchinterval()`. + + - Forced thread switching when releasing the GIL is implemented. When + a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. It does so + by waiting on a variable (gil_last_holder) controlled through another + {mutex, condition} pair. + + - An optional policy mechanism, priority requests, is currently disabled. + The intent was to further improve the latency of some types of GIL-taking + activities, such as being woken up on a socket. If it is confirmed that + this feature is unnecessary, support code should be removed. +*/ + #ifndef _POSIX_THREADS /* This means pthreads are not implemented in libc headers, hence the macro not present in unistd.h. But they still can be implemented as an external From python-checkins at python.org Wed Nov 4 22:10:39 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 04 Nov 2009 21:10:39 -0000 Subject: [Python-checkins] r76111 - in python/branches/py3k: Lib/test/test_kqueue.py Misc/ACKS Misc/NEWS Modules/selectmodule.c Message-ID: Author: antoine.pitrou Date: Wed Nov 4 22:10:38 2009 New Revision: 76111 Log: Merged revisions 76108 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76108 | antoine.pitrou | 2009-11-04 20:25:14 +0100 (mer., 04 nov. 2009) | 6 lines Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent objects on 64-bit systems. Patch by Michael Broghton. I will revert this checkin if it causes problems on our BSD buildbots. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_kqueue.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/selectmodule.c Modified: python/branches/py3k/Lib/test/test_kqueue.py ============================================================================== --- python/branches/py3k/Lib/test/test_kqueue.py (original) +++ python/branches/py3k/Lib/test/test_kqueue.py Wed Nov 4 22:10:38 2009 @@ -71,6 +71,17 @@ self.assertEqual(ev, ev) self.assertNotEqual(ev, other) + bignum = sys.maxsize * 2 + 1 + ev = select.kevent(bignum, 1, 2, 3, sys.maxsize, bignum) + self.assertEqual(ev.ident, bignum) + self.assertEqual(ev.filter, 1) + self.assertEqual(ev.flags, 2) + self.assertEqual(ev.fflags, 3) + self.assertEqual(ev.data, sys.maxsize) + self.assertEqual(ev.udata, bignum) + self.assertEqual(ev, ev) + self.assertNotEqual(ev, other) + def test_queue_event(self): serverSocket = socket.socket() serverSocket.bind(('127.0.0.1', 0)) Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Nov 4 22:10:38 2009 @@ -95,6 +95,7 @@ Dave Brennan Tom Bridgman Richard Brodie +Michael Broghton Daniel Brotsky Jean Brouwers Gary S. Brown Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Nov 4 22:10:38 2009 @@ -123,6 +123,9 @@ Library ------- +- Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent + objects on 64-bit systems. Patch by Michael Broghton. + - Issue #6896: mailbox.Maildir now invalidates its internal cache each time a modification is done through it. This fixes inconsistencies and test failures on systems with slightly bogus mtime behaviour. Modified: python/branches/py3k/Modules/selectmodule.c ============================================================================== --- python/branches/py3k/Modules/selectmodule.c (original) +++ python/branches/py3k/Modules/selectmodule.c Wed Nov 4 22:10:38 2009 @@ -1199,6 +1199,30 @@ #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type)) +#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) +# error uintptr_t does not match void *! +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) +# define T_UINTPTRT T_ULONGLONG +# define T_INTPTRT T_LONGLONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong +# define UINTPTRT_FMT_UNIT "K" +# define INTPTRT_FMT_UNIT "L" +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) +# define T_UINTPTRT T_ULONG +# define T_INTPTRT T_LONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "k" +# define INTPTRT_FMT_UNIT "l" +#elif (SIZEOF_UINTPTR_T == SIZEOF_INT) +# define T_UINTPTRT T_UINT +# define T_INTPTRT T_INT +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "I" +# define INTPTRT_FMT_UNIT "i" +#else +# error uintptr_t does not match int, long, or long long! +#endif + /* Unfortunately, we can't store python objects in udata, because * kevents in the kernel can be removed without warning, which would * forever lose the refcount on the object stored with it. @@ -1206,12 +1230,12 @@ #define KQ_OFF(x) offsetof(kqueue_event_Object, x) static struct PyMemberDef kqueue_event_members[] = { - {"ident", T_UINT, KQ_OFF(e.ident)}, + {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, {"filter", T_SHORT, KQ_OFF(e.filter)}, {"flags", T_USHORT, KQ_OFF(e.flags)}, {"fflags", T_UINT, KQ_OFF(e.fflags)}, - {"data", T_INT, KQ_OFF(e.data)}, - {"udata", T_INT, KQ_OFF(e.udata)}, + {"data", T_INTPTRT, KQ_OFF(e.data)}, + {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, {NULL} /* Sentinel */ }; #undef KQ_OFF @@ -1222,11 +1246,11 @@ char buf[1024]; PyOS_snprintf( buf, sizeof(buf), - "", - (unsigned long)(s->e.ident), s->e.filter, s->e.flags, - s->e.fflags, (long)(s->e.data), s->e.udata); - return PyBytes_FromString(buf); + "", + (size_t)(s->e.ident), s->e.filter, s->e.flags, + s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata); + return PyUnicode_FromString(buf); } static int @@ -1235,17 +1259,23 @@ PyObject *pfd; static char *kwlist[] = {"ident", "filter", "flags", "fflags", "data", "udata", NULL}; + static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, &pfd, &(self->e.filter), &(self->e.flags), &(self->e.fflags), &(self->e.data), &(self->e.udata))) { return -1; } - self->e.ident = PyObject_AsFileDescriptor(pfd); - if (self->e.ident == -1) { + if (PyLong_Check(pfd)) { + self->e.ident = PyLong_AsUintptr_t(pfd); + } + else { + self->e.ident = PyObject_AsFileDescriptor(pfd); + } + if (PyErr_Occurred()) { return -1; } return 0; @@ -1255,7 +1285,7 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, int op) { - int result = 0; + Py_intptr_t result = 0; if (!kqueue_event_Check(o)) { if (op == Py_EQ || op == Py_NE) { @@ -1298,7 +1328,7 @@ result = (result > 0); break; } - return PyBool_FromLong(result); + return PyBool_FromLong((long)result); } static PyTypeObject kqueue_event_Type = { From python-checkins at python.org Wed Nov 4 22:39:10 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 04 Nov 2009 21:39:10 -0000 Subject: [Python-checkins] r76112 - peps/trunk/pep-3003.txt Message-ID: Author: brett.cannon Date: Wed Nov 4 22:39:10 2009 New Revision: 76112 Log: Mention that no commit rollbacks are needed. Modified: peps/trunk/pep-3003.txt Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Wed Nov 4 22:39:10 2009 @@ -126,6 +126,8 @@ It is important to note that the moratorium covers all changes since the release of Python 3.1. This rule is intended to avoid features being rushed or smuggled into the CPython source tree while the moratorium is being discussed. +A review of the NEWS file for the py3k development branch showed no +commits would need to be rolled back in order to meet this goal. Copyright From nnorwitz at gmail.com Wed Nov 4 23:57:42 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 4 Nov 2009 17:57:42 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091104225742.GA27261@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [-81, 0, 420] references, sum=339 Less important issues: ---------------------- test_threading leaked [48, 48, 48] references, sum=144 From python-checkins at python.org Thu Nov 5 02:17:22 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 05 Nov 2009 01:17:22 -0000 Subject: [Python-checkins] r76113 - in python/branches/py3k: Lib/importlib/test/source/util.py Misc/NEWS Message-ID: Author: brett.cannon Date: Thu Nov 5 02:17:22 2009 New Revision: 76113 Log: importlib.test.source.util referenced variables in the 'finally' part of a try/finally which may not have been set. Modified: python/branches/py3k/Lib/importlib/test/source/util.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/importlib/test/source/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/source/util.py (original) +++ python/branches/py3k/Lib/importlib/test/source/util.py Thu Nov 5 02:17:22 2009 @@ -55,6 +55,8 @@ source = 'attr = {0!r}' created_paths = [] mapping = {} + state_manager = None + uncache_manager = None try: temp_dir = tempfile.gettempdir() mapping['.root'] = temp_dir @@ -85,8 +87,10 @@ state_manager.__enter__() yield mapping finally: - state_manager.__exit__(None, None, None) - uncache_manager.__exit__(None, None, None) + if state_manager is not None: + state_manager.__exit__(None, None, None) + if uncache_manager is not None: + uncache_manager.__exit__(None, None, None) # Reverse the order for path removal to unroll directory creation. for path in reversed(created_paths): if file_path.endswith('.py'): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 5 02:17:22 2009 @@ -354,6 +354,10 @@ Tests ----- +- Issue #7248: In importlib.test.source.util a try/finally block did not make + sure that some referenced objects actually were created in the block before + calling methods on the object. + - Issue #7222: Make thread "reaping" more reliable so that reference leak-chasing test runs give sensible results. The previous method of reaping threads could return successfully while some Thread objects were From python-checkins at python.org Thu Nov 5 02:26:57 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 05 Nov 2009 01:26:57 -0000 Subject: [Python-checkins] r76114 - in python/branches/py3k: Lib/importlib/test/source/util.py Misc/NEWS Message-ID: Author: brett.cannon Date: Thu Nov 5 02:26:57 2009 New Revision: 76114 Log: Use tempfile.mkdtemp() instead of tempfile.tempdir for where importlib places source files for tests. Allows for concurrent execution of the tests by preventing various executions from trampling each other. Closes issue #7248. Modified: python/branches/py3k/Lib/importlib/test/source/util.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/importlib/test/source/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/source/util.py (original) +++ python/branches/py3k/Lib/importlib/test/source/util.py Thu Nov 5 02:26:57 2009 @@ -42,8 +42,8 @@ that contains the name passed into the context manager that caused the creation of the module. - All files are created in a temporary directory specified by - tempfile.gettempdir(). This directory is inserted at the beginning of + All files are created in a temporary directory returned by + tempfile.mkdtemp(). This directory is inserted at the beginning of sys.path. When the context manager exits all created files (source and bytecode) are explicitly deleted. @@ -58,7 +58,7 @@ state_manager = None uncache_manager = None try: - temp_dir = tempfile.gettempdir() + temp_dir = tempfile.mkdtemp() mapping['.root'] = temp_dir import_names = set() for name in names: @@ -91,11 +91,4 @@ state_manager.__exit__(None, None, None) if uncache_manager is not None: uncache_manager.__exit__(None, None, None) - # Reverse the order for path removal to unroll directory creation. - for path in reversed(created_paths): - if file_path.endswith('.py'): - support.unlink(path) - support.unlink(path + 'c') - support.unlink(path + 'o') - else: - os.rmdir(path) + support.rmtree(temp_dir) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 5 02:26:57 2009 @@ -354,6 +354,10 @@ Tests ----- +- Issue #7248 (part 2): Use a unique temporary directory for importlib source + tests instead of tempfile.tempdir. This prevents the tests from sharing state + between concurrent executions on the same system. + - Issue #7248: In importlib.test.source.util a try/finally block did not make sure that some referenced objects actually were created in the block before calling methods on the object. From python-checkins at python.org Thu Nov 5 02:34:30 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 05 Nov 2009 01:34:30 -0000 Subject: [Python-checkins] r76115 - in python/branches/release31-maint: Lib/importlib/test/source/util.py Misc/NEWS Message-ID: Author: brett.cannon Date: Thu Nov 5 02:34:30 2009 New Revision: 76115 Log: Merged revisions 76113-76114 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76113 | brett.cannon | 2009-11-04 17:17:22 -0800 (Wed, 04 Nov 2009) | 3 lines importlib.test.source.util referenced variables in the 'finally' part of a try/finally which may not have been set. ........ r76114 | brett.cannon | 2009-11-04 17:26:57 -0800 (Wed, 04 Nov 2009) | 6 lines Use tempfile.mkdtemp() instead of tempfile.tempdir for where importlib places source files for tests. Allows for concurrent execution of the tests by preventing various executions from trampling each other. Closes issue #7248. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/importlib/test/source/util.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/importlib/test/source/util.py ============================================================================== --- python/branches/release31-maint/Lib/importlib/test/source/util.py (original) +++ python/branches/release31-maint/Lib/importlib/test/source/util.py Thu Nov 5 02:34:30 2009 @@ -42,8 +42,8 @@ that contains the name passed into the context manager that caused the creation of the module. - All files are created in a temporary directory specified by - tempfile.gettempdir(). This directory is inserted at the beginning of + All files are created in a temporary directory returned by + tempfile.mkdtemp(). This directory is inserted at the beginning of sys.path. When the context manager exits all created files (source and bytecode) are explicitly deleted. @@ -55,8 +55,10 @@ source = 'attr = {0!r}' created_paths = [] mapping = {} + state_manager = None + uncache_manager = None try: - temp_dir = tempfile.gettempdir() + temp_dir = tempfile.mkdtemp() mapping['.root'] = temp_dir import_names = set() for name in names: @@ -85,13 +87,8 @@ state_manager.__enter__() yield mapping finally: - state_manager.__exit__(None, None, None) - uncache_manager.__exit__(None, None, None) - # Reverse the order for path removal to unroll directory creation. - for path in reversed(created_paths): - if file_path.endswith('.py'): - support.unlink(path) - support.unlink(path + 'c') - support.unlink(path + 'o') - else: - os.rmdir(path) + if state_manager is not None: + state_manager.__exit__(None, None, None) + if uncache_manager is not None: + uncache_manager.__exit__(None, None, None) + support.rmtree(temp_dir) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 5 02:34:30 2009 @@ -134,6 +134,14 @@ Tests ----- +- Issue #7248 (part 2): Use a unique temporary directory for importlib source + tests instead of tempfile.tempdir. This prevents the tests from sharing state + between concurrent executions on the same system. + +- Issue #7248: In importlib.test.source.util a try/finally block did not make + sure that some referenced objects actually were created in the block before + calling methods on the object. + - Issue #7055: test___all__ now greedily detects all modules which have an __all__ attribute, rather than using a hardcoded and incomplete list. From python-checkins at python.org Thu Nov 5 02:50:56 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 05 Nov 2009 01:50:56 -0000 Subject: [Python-checkins] r76116 - python/trunk/Lib/bsddb/test/test_replication.py Message-ID: Author: r.david.murray Date: Thu Nov 5 02:50:56 2009 New Revision: 76116 Log: Increase the timeout in the bsddb3 replication test to allow the test time to complete on slow buildbots. See issue 6462. Modified: python/trunk/Lib/bsddb/test/test_replication.py Modified: python/trunk/Lib/bsddb/test/test_replication.py ============================================================================== --- python/trunk/Lib/bsddb/test/test_replication.py (original) +++ python/trunk/Lib/bsddb/test/test_replication.py Thu Nov 5 02:50:56 2009 @@ -116,7 +116,7 @@ # is not generated if the master has no new transactions. # This is solved in BDB 4.6 (#15542). import time - timeout = time.time()+10 + timeout = time.time()+30 while (time.time() Author: antoine.pitrou Date: Thu Nov 5 14:42:29 2009 New Revision: 76117 Log: Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. Modified: python/trunk/Lib/_threading_local.py python/trunk/Lib/threading.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/_threading_local.py ============================================================================== --- python/trunk/Lib/_threading_local.py (original) +++ python/trunk/Lib/_threading_local.py Thu Nov 5 14:42:29 2009 @@ -218,10 +218,12 @@ key = object.__getattribute__(self, '_local__key') try: - threads = list(threading.enumerate()) + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() except: - # If enumerate fails, as it seems to do during - # shutdown, we'll skip cleanup under the assumption + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up. return Modified: python/trunk/Lib/threading.py ============================================================================== --- python/trunk/Lib/threading.py (original) +++ python/trunk/Lib/threading.py Thu Nov 5 14:42:29 2009 @@ -810,6 +810,10 @@ active_count = activeCount +def _enumerate(): + # Same as enumerate(), but without the lock. Internal use only. + return _active.values() + _limbo.values() + def enumerate(): with _active_limbo_lock: return _active.values() + _limbo.values() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Nov 5 14:42:29 2009 @@ -426,6 +426,9 @@ Library ------- +- Issue #7264: Fix a possible deadlock when deallocating thread-local objects + which are part of a reference cycle. + - Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent objects on 64-bit systems. Patch by Michael Broghton. From python-checkins at python.org Thu Nov 5 14:44:29 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 05 Nov 2009 13:44:29 -0000 Subject: [Python-checkins] r76118 - in python/branches/release26-maint: Lib/_threading_local.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Thu Nov 5 14:44:28 2009 New Revision: 76118 Log: Merged revisions 76117 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76117 | antoine.pitrou | 2009-11-05 14:42:29 +0100 (jeu., 05 nov. 2009) | 5 lines Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/_threading_local.py python/branches/release26-maint/Lib/threading.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/_threading_local.py ============================================================================== --- python/branches/release26-maint/Lib/_threading_local.py (original) +++ python/branches/release26-maint/Lib/_threading_local.py Thu Nov 5 14:44:28 2009 @@ -218,10 +218,12 @@ key = object.__getattribute__(self, '_local__key') try: - threads = list(threading.enumerate()) + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() except: - # If enumerate fails, as it seems to do during - # shutdown, we'll skip cleanup under the assumption + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up. return Modified: python/branches/release26-maint/Lib/threading.py ============================================================================== --- python/branches/release26-maint/Lib/threading.py (original) +++ python/branches/release26-maint/Lib/threading.py Thu Nov 5 14:44:28 2009 @@ -815,6 +815,10 @@ active_count = activeCount +def _enumerate(): + # Same as enumerate(), but without the lock. Internal use only. + return _active.values() + _limbo.values() + def enumerate(): _active_limbo_lock.acquire() active = _active.values() + _limbo.values() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Nov 5 14:44:28 2009 @@ -24,6 +24,9 @@ Library ------- +- Issue #7264: Fix a possible deadlock when deallocating thread-local objects + which are part of a reference cycle. + - Issue #7249: Methods of io.BytesIO now allow `long` as well as `int` arguments. From python-checkins at python.org Thu Nov 5 14:49:14 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 05 Nov 2009 13:49:14 -0000 Subject: [Python-checkins] r76119 - in python/branches/py3k: Lib/_threading_local.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Thu Nov 5 14:49:14 2009 New Revision: 76119 Log: Merged revisions 76117 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76117 | antoine.pitrou | 2009-11-05 14:42:29 +0100 (jeu., 05 nov. 2009) | 5 lines Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/_threading_local.py python/branches/py3k/Lib/threading.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/_threading_local.py ============================================================================== --- python/branches/py3k/Lib/_threading_local.py (original) +++ python/branches/py3k/Lib/_threading_local.py Thu Nov 5 14:49:14 2009 @@ -217,10 +217,12 @@ key = object.__getattribute__(self, '_local__key') try: - threads = list(threading.enumerate()) + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() except: - # If enumerate fails, as it seems to do during - # shutdown, we'll skip cleanup under the assumption + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up. return Modified: python/branches/py3k/Lib/threading.py ============================================================================== --- python/branches/py3k/Lib/threading.py (original) +++ python/branches/py3k/Lib/threading.py Thu Nov 5 14:49:14 2009 @@ -798,6 +798,10 @@ activeCount = active_count +def _enumerate(): + # Same as enumerate(), but without the lock. Internal use only. + return list(_active.values()) + list(_limbo.values()) + def enumerate(): with _active_limbo_lock: return list(_active.values()) + list(_limbo.values()) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 5 14:49:14 2009 @@ -123,6 +123,9 @@ Library ------- +- Issue #7264: Fix a possible deadlock when deallocating thread-local objects + which are part of a reference cycle. + - Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent objects on 64-bit systems. Patch by Michael Broghton. From python-checkins at python.org Thu Nov 5 14:51:19 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 05 Nov 2009 13:51:19 -0000 Subject: [Python-checkins] r76120 - in python/branches/release31-maint: Lib/_threading_local.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Thu Nov 5 14:51:19 2009 New Revision: 76120 Log: Merged revisions 76119 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76119 | antoine.pitrou | 2009-11-05 14:49:14 +0100 (jeu., 05 nov. 2009) | 10 lines Merged revisions 76117 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76117 | antoine.pitrou | 2009-11-05 14:42:29 +0100 (jeu., 05 nov. 2009) | 5 lines Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/_threading_local.py python/branches/release31-maint/Lib/threading.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/_threading_local.py ============================================================================== --- python/branches/release31-maint/Lib/_threading_local.py (original) +++ python/branches/release31-maint/Lib/_threading_local.py Thu Nov 5 14:51:19 2009 @@ -217,10 +217,12 @@ key = object.__getattribute__(self, '_local__key') try: - threads = list(threading.enumerate()) + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() except: - # If enumerate fails, as it seems to do during - # shutdown, we'll skip cleanup under the assumption + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up. return Modified: python/branches/release31-maint/Lib/threading.py ============================================================================== --- python/branches/release31-maint/Lib/threading.py (original) +++ python/branches/release31-maint/Lib/threading.py Thu Nov 5 14:51:19 2009 @@ -798,6 +798,10 @@ activeCount = active_count +def _enumerate(): + # Same as enumerate(), but without the lock. Internal use only. + return list(_active.values()) + list(_limbo.values()) + def enumerate(): with _active_limbo_lock: return list(_active.values()) + list(_limbo.values()) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 5 14:51:19 2009 @@ -40,6 +40,9 @@ Library ------- +- Issue #7264: Fix a possible deadlock when deallocating thread-local objects + which are part of a reference cycle. + - Issue #6896: mailbox.Maildir now invalidates its internal cache each time a modification is done through it. This fixes inconsistencies and test failures on systems with slightly bogus mtime behaviour. From python-checkins at python.org Thu Nov 5 15:08:07 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 05 Nov 2009 14:08:07 -0000 Subject: [Python-checkins] r76121 - in python/branches/release26-maint: Lib/bsddb/test/test_replication.py Message-ID: Author: r.david.murray Date: Thu Nov 5 15:08:06 2009 New Revision: 76121 Log: Merged revisions 76116 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76116 | r.david.murray | 2009-11-04 20:50:56 -0500 (Wed, 04 Nov 2009) | 3 lines Increase the timeout in the bsddb3 replication test to allow the test time to complete on slow buildbots. See issue 6462. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/bsddb/test/test_replication.py Modified: python/branches/release26-maint/Lib/bsddb/test/test_replication.py ============================================================================== --- python/branches/release26-maint/Lib/bsddb/test/test_replication.py (original) +++ python/branches/release26-maint/Lib/bsddb/test/test_replication.py Thu Nov 5 15:08:06 2009 @@ -116,7 +116,7 @@ # is not generated if the master has no new transactions. # This is solved in BDB 4.6 (#15542). import time - timeout = time.time()+10 + timeout = time.time()+30 while (time.time() Author: phillip.eby Date: Thu Nov 5 16:58:09 2009 New Revision: 76122 Log: Fix incorrect error message/traceback when no download is found. Modified: sandbox/trunk/setuptools/setuptools/package_index.py Modified: sandbox/trunk/setuptools/setuptools/package_index.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/package_index.py (original) +++ sandbox/trunk/setuptools/setuptools/package_index.py Thu Nov 5 16:58:09 2009 @@ -471,8 +471,9 @@ (source and "a source distribution of " or ""), requirement, ) - self.info("Best match: %s", dist) - return dist.clone(location=self.download(dist.location, tmpdir)) + else: + self.info("Best match: %s", dist) + return dist.clone(location=self.download(dist.location, tmpdir)) def fetch(self, requirement, tmpdir, force_scan=False, source=False): @@ -489,7 +490,6 @@ return None - def gen_setup(self, filename, fragment, tmpdir): match = EGG_FRAGMENT.match(fragment) dists = match and [d for d in From python-checkins at python.org Thu Nov 5 17:00:26 2009 From: python-checkins at python.org (phillip.eby) Date: Thu, 05 Nov 2009 16:00:26 -0000 Subject: [Python-checkins] r76123 - in sandbox/branches/setuptools-0.6: EasyInstall.txt setuptools/package_index.py Message-ID: Author: phillip.eby Date: Thu Nov 5 17:00:25 2009 New Revision: 76123 Log: Backport to 0.6 Modified: sandbox/branches/setuptools-0.6/EasyInstall.txt sandbox/branches/setuptools-0.6/setuptools/package_index.py Modified: sandbox/branches/setuptools-0.6/EasyInstall.txt ============================================================================== --- sandbox/branches/setuptools-0.6/EasyInstall.txt (original) +++ sandbox/branches/setuptools-0.6/EasyInstall.txt Thu Nov 5 17:00:25 2009 @@ -1221,6 +1221,9 @@ * Fixed AttributeError under Python 2.3 when processing "HTTP authentication" URLs (i.e., ones with a ``user:password at host``). + * Fixed bogus AttributeError when no local or downloadable packages are + available + 0.6c11 * Fix installed script .exe files not working with 64-bit Python on Windows (wasn't actually released in 0.6c10 due to a lost checkin) Modified: sandbox/branches/setuptools-0.6/setuptools/package_index.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/package_index.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/package_index.py Thu Nov 5 17:00:25 2009 @@ -471,8 +471,9 @@ (source and "a source distribution of " or ""), requirement, ) - self.info("Best match: %s", dist) - return dist.clone(location=self.download(dist.location, tmpdir)) + else: + self.info("Best match: %s", dist) + return dist.clone(location=self.download(dist.location, tmpdir)) def fetch(self, requirement, tmpdir, force_scan=False, source=False): @@ -489,7 +490,6 @@ return None - def gen_setup(self, filename, fragment, tmpdir): match = EGG_FRAGMENT.match(fragment) dists = match and [d for d in From python-checkins at python.org Thu Nov 5 18:49:11 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 05 Nov 2009 17:49:11 -0000 Subject: [Python-checkins] r76124 - python/branches/py3k Message-ID: Author: r.david.murray Date: Thu Nov 5 18:49:10 2009 New Revision: 76124 Log: Blocked revisions 76116 via svnmerge ........ r76116 | r.david.murray | 2009-11-04 20:50:56 -0500 (Wed, 04 Nov 2009) | 3 lines Increase the timeout in the bsddb3 replication test to allow the test time to complete on slow buildbots. See issue 6462. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Nov 5 22:26:55 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 21:26:55 -0000 Subject: [Python-checkins] r76125 - sandbox/trunk/2to3/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Thu Nov 5 22:26:55 2009 New Revision: 76125 Log: handle newline issues better for comparing files Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_parser.py Thu Nov 5 22:26:55 2009 @@ -12,6 +12,7 @@ # Python imports import os +import io # Local imports from lib2to3.pgen2 import tokenize @@ -149,15 +150,13 @@ for filepath in support.all_project_files(): with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] - fp.seek(0) + self.assertTrue(encoding is not None, + "can't detect encoding for %s" % filepath) + with io.open(filepath, "r", encoding=encoding) as fp: source = fp.read() - if encoding: - source = source.decode(encoding) tree = driver.parse_string(source) new = unicode(tree) - if encoding: - new = new.encode(encoding) - if diff(filepath, new): + if diff(filepath, new, encoding): self.fail("Idempotency failed: %s" % filepath) def test_extended_unpacking(self): @@ -199,8 +198,8 @@ self.validate(s) -def diff(fn, result): - f = open("@", "wb") +def diff(fn, result, encoding): + f = io.open("@", "w", encoding=encoding) try: f.write(result) finally: From python-checkins at python.org Thu Nov 5 22:29:57 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 21:29:57 -0000 Subject: [Python-checkins] r76126 - in python/trunk/Lib/lib2to3: tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Thu Nov 5 22:29:56 2009 New Revision: 76126 Log: Merged revisions 76125 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76125 | benjamin.peterson | 2009-11-05 15:26:55 -0600 (Thu, 05 Nov 2009) | 1 line handle newline issues better for comparing files ........ Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/tests/test_parser.py Modified: python/trunk/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_parser.py (original) +++ python/trunk/Lib/lib2to3/tests/test_parser.py Thu Nov 5 22:29:56 2009 @@ -12,6 +12,7 @@ # Python imports import os +import io # Local imports from lib2to3.pgen2 import tokenize @@ -149,15 +150,13 @@ for filepath in support.all_project_files(): with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] - fp.seek(0) + self.assertTrue(encoding is not None, + "can't detect encoding for %s" % filepath) + with io.open(filepath, "r", encoding=encoding) as fp: source = fp.read() - if encoding: - source = source.decode(encoding) tree = driver.parse_string(source) new = unicode(tree) - if encoding: - new = new.encode(encoding) - if diff(filepath, new): + if diff(filepath, new, encoding): self.fail("Idempotency failed: %s" % filepath) def test_extended_unpacking(self): @@ -199,8 +198,8 @@ self.validate(s) -def diff(fn, result): - f = open("@", "wb") +def diff(fn, result, encoding): + f = io.open("@", "w", encoding=encoding) try: f.write(result) finally: From nnorwitz at gmail.com Thu Nov 5 23:57:37 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 5 Nov 2009 17:57:37 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091105225737.GA28785@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [-420, 420, -420] references, sum=-420 Less important issues: ---------------------- test_distutils leaked [0, 25, -25] references, sum=0 test_threading leaked [48, 48, 48] references, sum=144 test_zipimport_support leaked [-25, 25, 0] references, sum=0 From python-checkins at python.org Fri Nov 6 00:04:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 23:04:59 -0000 Subject: [Python-checkins] r76127 - sandbox/trunk/2to3/lib2to3/fixes/fix_operator.py Message-ID: Author: benjamin.peterson Date: Fri Nov 6 00:04:58 2009 New Revision: 76127 Log: set svn:eol-style Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_operator.py (props changed) From python-checkins at python.org Fri Nov 6 00:07:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 23:07:47 -0000 Subject: [Python-checkins] r76128 - sandbox/trunk/2to3/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Fri Nov 6 00:07:46 2009 New Revision: 76128 Log: skip this test on windows to avoid newline horrors Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_parser.py Fri Nov 6 00:07:46 2009 @@ -147,6 +147,9 @@ """A cut-down version of pytree_idempotency.py.""" def test_all_project_files(self): + if sys.platform.startswith("win"): + # XXX something with newlines goes wrong on Windows. + return for filepath in support.all_project_files(): with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] From python-checkins at python.org Fri Nov 6 00:20:06 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 23:20:06 -0000 Subject: [Python-checkins] r76129 - in python/trunk/Lib/lib2to3: fixes/fix_operator.py tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Fri Nov 6 00:20:06 2009 New Revision: 76129 Log: Merged revisions 76127-76128 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76127 | benjamin.peterson | 2009-11-05 17:04:58 -0600 (Thu, 05 Nov 2009) | 1 line set svn:eol-style ........ r76128 | benjamin.peterson | 2009-11-05 17:07:46 -0600 (Thu, 05 Nov 2009) | 1 line skip this test on windows to avoid newline horrors ........ Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/fixes/fix_operator.py (props changed) python/trunk/Lib/lib2to3/tests/test_parser.py Modified: python/trunk/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_parser.py (original) +++ python/trunk/Lib/lib2to3/tests/test_parser.py Fri Nov 6 00:20:06 2009 @@ -147,6 +147,9 @@ """A cut-down version of pytree_idempotency.py.""" def test_all_project_files(self): + if sys.platform.startswith("win"): + # XXX something with newlines goes wrong on Windows. + return for filepath in support.all_project_files(): with open(filepath, "rb") as fp: encoding = tokenize.detect_encoding(fp.readline)[0] From python-checkins at python.org Fri Nov 6 00:22:00 2009 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 05 Nov 2009 23:22:00 -0000 Subject: [Python-checkins] r76130 - peps/trunk/pep-3003.txt Message-ID: Author: guido.van.rossum Date: Fri Nov 6 00:22:00 2009 New Revision: 76130 Log: Clarify that new __future__ imports are not allowed. Modified: peps/trunk/pep-3003.txt Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Fri Nov 6 00:22:00 2009 @@ -84,6 +84,9 @@ * General language semantics The language operates as-is with only specific exemptions (see below). +* New __future__ imports + These are explicitly forbidden, as they effectively change the language + syntax and/or semantics (albeit using a compiler directive). Case-by-Case Exemptions From python-checkins at python.org Fri Nov 6 00:53:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 23:53:21 -0000 Subject: [Python-checkins] r76131 - sandbox/trunk/2to3/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Fri Nov 6 00:53:21 2009 New Revision: 76131 Log: import sys Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_parser.py Fri Nov 6 00:53:21 2009 @@ -13,6 +13,7 @@ # Python imports import os import io +import sys # Local imports from lib2to3.pgen2 import tokenize From python-checkins at python.org Fri Nov 6 00:54:42 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 05 Nov 2009 23:54:42 -0000 Subject: [Python-checkins] r76132 - in python/trunk/Lib/lib2to3: tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Fri Nov 6 00:54:42 2009 New Revision: 76132 Log: Merged revisions 76131 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76131 | benjamin.peterson | 2009-11-05 17:53:21 -0600 (Thu, 05 Nov 2009) | 1 line import sys ........ Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/tests/test_parser.py Modified: python/trunk/Lib/lib2to3/tests/test_parser.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_parser.py (original) +++ python/trunk/Lib/lib2to3/tests/test_parser.py Fri Nov 6 00:54:42 2009 @@ -13,6 +13,7 @@ # Python imports import os import io +import sys # Local imports from lib2to3.pgen2 import tokenize From solipsis at pitrou.net Fri Nov 6 12:35:31 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Fri, 6 Nov 2009 11:35:31 +0000 (UTC) Subject: [Python-checkins] =?utf-8?q?r76128_-=09sandbox/trunk/2to3/lib2to3?= =?utf-8?q?/tests/test=5Fparser=2Epy?= References: <18471.4074865498$1257462616@news.gmane.org> Message-ID: writes: > > def test_all_project_files(self): > + if sys.platform.startswith("win"): > + # XXX something with newlines goes wrong on Windows. > + return You could have used the test skipping API... cheers Antoine. From benjamin at python.org Fri Nov 6 13:40:15 2009 From: benjamin at python.org (Benjamin Peterson) Date: Fri, 6 Nov 2009 06:40:15 -0600 Subject: [Python-checkins] r76128 - sandbox/trunk/2to3/lib2to3/tests/test_parser.py In-Reply-To: References: <18471.4074865498$1257462616@news.gmane.org> Message-ID: <1afaf6160911060440m7c0cf71co6dabd0ee784283ea@mail.gmail.com> 2009/11/6 Antoine Pitrou : > writes: >> >> ? ? ?def test_all_project_files(self): >> + ? ? ? ?if sys.platform.startswith("win"): >> + ? ? ? ? ? ?# XXX something with newlines goes wrong on Windows. >> + ? ? ? ? ? ?return > > You could have used the test skipping API... Unfortunately, no, because that's not in 2.6. -- Regards, Benjamin From python-checkins at python.org Fri Nov 6 18:20:42 2009 From: python-checkins at python.org (jack.diederich) Date: Fri, 06 Nov 2009 17:20:42 -0000 Subject: [Python-checkins] r76133 - python/branches/py3k/Lib/test/test_telnetlib.py Message-ID: Author: jack.diederich Date: Fri Nov 6 18:20:42 2009 New Revision: 76133 Log: - issue #6748 intermittent test failures from sockets - telnetlib tests now use mock sockets for most tests Modified: python/branches/py3k/Lib/test/test_telnetlib.py Modified: python/branches/py3k/Lib/test/test_telnetlib.py ============================================================================== --- python/branches/py3k/Lib/test/test_telnetlib.py (original) +++ python/branches/py3k/Lib/test/test_telnetlib.py Fri Nov 6 18:20:42 2009 @@ -1,48 +1,23 @@ import socket +import select import threading import telnetlib import time -import queue -import sys -import io +import contextlib from unittest import TestCase from test import support HOST = support.HOST -EOF_sigil = object() -def server(evt, serv, dataq=None, test_done=None): - """ Open a tcp server in four steps - 1) set evt to true to let the parent know we are ready - 2) [optional] if is not False, write the list of data from dataq.get() - to the socket. - 3) [optional] if test_done is not None, it's an event; wait - for parent to set test_done before closing connection - 4) set evt to true to let the parent know we're done - """ +def server(evt, serv): serv.listen(5) evt.set() try: conn, addr = serv.accept() - if dataq: - data = b'' - new_data = dataq.get(True, 0.5) - dataq.task_done() - for item in new_data: - if item == EOF_sigil: - break - if type(item) in [int, float]: - time.sleep(item) - else: - data += item - written = conn.send(data) - data = data[written:] except socket.timeout: pass finally: - if test_done is not None: - test_done.wait() serv.close() evt.set() @@ -100,163 +75,159 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() -def _read_setUp(self): - self.evt = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - -def _read_tearDown(self): - self.evt.wait() - self.thread.join() +class SocketStub(object): + ''' a socket proxy that re-defines sendall() ''' + def __init__(self, reads=[]): + self.reads = reads + self.writes = [] + self.block = False + def sendall(self, data): + self.writes.append(data) + def recv(self, size): + out = b'' + while self.reads and len(out) < size: + out += self.reads.pop(0) + if len(out) > size: + self.reads.insert(0, out[size:]) + out = out[:size] + return out + +class TelnetAlike(telnetlib.Telnet): + def fileno(self): + raise NotImplementedError() + def close(self): pass + def sock_avail(self): + return (not self.sock.block) + def msg(self, msg, *args): + with support.captured_stdout() as out: + telnetlib.Telnet.msg(self, msg, *args) + self._messages += out.getvalue() + return + +def new_select(*s_args): + block = False + for l in s_args: + for fob in l: + if isinstance(fob, TelnetAlike): + block = fob.sock.block + if block: + return [[], [], []] + else: + return s_args + + at contextlib.contextmanager +def test_socket(reads): + def new_conn(*ignored): + return SocketStub(reads) + try: + old_conn = socket.create_connection + socket.create_connection = new_conn + yield None + finally: + socket.create_connection = old_conn + return + +def test_telnet(reads=[], cls=TelnetAlike): + ''' return a telnetlib.Telnet object that uses a SocketStub with + reads queued up to be read ''' + for x in reads: + assert type(x) is bytes, x + with test_socket(reads): + telnet = cls('dummy', 0) + telnet._messages = '' # debuglevel output + return telnet class ReadTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown + def setUp(self): + self.old_select = select.select + select.select = new_select + def tearDown(self): + select.select = self.old_select - # use a similar approach to testing timeouts as test_timeout.py - # these will never pass 100% but make the fuzz big enough that it is rare - block_long = 0.6 - block_short = 0.3 - def test_read_until_A(self): + def test_read_until(self): """ - read_until(expected, [timeout]) - Read until the expected string has been seen, or a timeout is - hit (default is no timeout); may block. + read_until(expected, timeout=None) + test the blocking version of read_util """ - want = [b'x' * 10, b'match', b'y' * 10, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = [b'xxxmatchyyy'] + telnet = test_telnet(want) data = telnet.read_until(b'match') - self.assertEqual(data, b''.join(want[:-2])) + self.assertEqual(data, b'xxxmatch', msg=(telnet.cookedq, telnet.rawq, telnet.sock.reads)) - def test_read_until_B(self): - # test the timeout - it does NOT raise socket.timeout - want = [b'hello', self.block_long, b'not seen', EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_until(b'not seen', self.block_short) - self.assertEqual(data, want[0]) - self.assertEqual(telnet.read_all(), b'not seen') + reads = [b'x' * 50, b'match', b'y' * 50] + expect = b''.join(reads[:-1]) + telnet = test_telnet(reads) + data = telnet.read_until(b'match') + self.assertEqual(data, expect) - def test_read_all_A(self): + + def test_read_all(self): """ read_all() Read all data until EOF; may block. """ - want = [b'x' * 500, b'y' * 500, b'z' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + reads = [b'x' * 500, b'y' * 500, b'z' * 500] + expect = b''.join(reads) + telnet = test_telnet(reads) data = telnet.read_all() - self.assertEqual(data, b''.join(want[:-1])) + self.assertEqual(data, expect) return - def _test_blocking(self, func): - self.dataq.put([self.block_long, EOF_sigil]) - self.dataq.join() - start = time.time() - data = func() - self.assertTrue(self.block_short <= time.time() - start) - - def test_read_all_B(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) - - def test_read_all_C(self): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - telnet.read_all() - telnet.read_all() # shouldn't raise - - def test_read_some_A(self): + def test_read_some(self): """ read_some() Read at least one byte or EOF; may block. """ # test 'at least one byte' - want = [b'x' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_all() + telnet = test_telnet([b'x' * 500]) + data = telnet.read_some() self.assertTrue(len(data) >= 1) - - def test_read_some_B(self): # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.assertEqual(b'', telnet.read_some()) - - def test_read_some_C(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) + telnet = test_telnet() + data = telnet.read_some() + self.assertEqual(b'', data) - def _test_read_any_eager_A(self, func_name): + def _read_eager(self, func_name): """ - read_very_eager() + read_*_eager() Read all data available already queued or on the socket, without blocking. """ - want = [self.block_long, b'x' * 100, b'y' * 100, EOF_sigil] - expects = want[1] + want[2] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = b'x' * 100 + telnet = test_telnet([want]) func = getattr(telnet, func_name) + telnet.sock.block = True + self.assertEqual(b'', func()) + telnet.sock.block = False data = b'' while True: try: data += func() - self.assertTrue(expects.startswith(data)) except EOFError: break - self.assertEqual(expects, data) - - def _test_read_any_eager_B(self, func_name): - # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - func = getattr(telnet, func_name) - self.assertRaises(EOFError, func) + self.assertEqual(data, want) - # read_eager and read_very_eager make the same gaurantees - # (they behave differently but we only test the gaurantees) - def test_read_very_eager_A(self): - self._test_read_any_eager_A('read_very_eager') - def test_read_very_eager_B(self): - self._test_read_any_eager_B('read_very_eager') - def test_read_eager_A(self): - self._test_read_any_eager_A('read_eager') - def test_read_eager_B(self): - self._test_read_any_eager_B('read_eager') - # NB -- we need to test the IAC block which is mentioned in the docstring - # but not in the module docs - - def _test_read_any_lazy_B(self, func_name): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - func = getattr(telnet, func_name) - telnet.fill_rawq() - self.assertRaises(EOFError, func) - - def test_read_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) + def test_read_eager(self): + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + self._read_eager('read_eager') + self._read_eager('read_very_eager') + # NB -- we need to test the IAC block which is mentioned in the + # docstring but not in the module docs + + def read_very_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) + self.assertEqual(b'', telnet.read_very_lazy()) + while telnet.sock.reads: + telnet.fill_rawq() + data = telnet.read_very_lazy() + self.assertEqual(want, data) + self.assertRaises(EOFError, telnet.read_very_lazy) + + def test_read_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) self.assertEqual(b'', telnet.read_lazy()) data = b'' while True: @@ -267,35 +238,8 @@ telnet.fill_rawq() except EOFError: break - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_lazy_B(self): - self._test_read_any_lazy_B('read_lazy') - - def test_read_very_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - self.assertEqual(b'', telnet.read_very_lazy()) - data = b'' - while True: - try: - read_data = telnet.read_very_lazy() - except EOFError: - break - data += read_data - if not read_data: - telnet.fill_rawq() - self.assertEqual(b'', telnet.cookedq) - telnet.process_rawq() - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_very_lazy_B(self): - self._test_read_any_lazy_B('read_very_lazy') + self.assertTrue(want.startswith(data)) + self.assertEqual(data, want) class nego_collector(object): def __init__(self, sb_getter=None): @@ -309,91 +253,32 @@ sb_data = self.sb_getter() self.sb_seen += sb_data -class SocketProxy(object): - ''' a socket proxy that re-defines sendall() ''' - def __init__(self, real_sock): - self.socket = real_sock - self._raw_sent = b'' - def __getattr__(self, k): - return getattr(self.socket, k) - def sendall(self, data): - self._raw_sent += data - self.socket.sendall(data) - -class TelnetSockSendall(telnetlib.Telnet): - def open(self, *args, **opts): - telnetlib.Telnet.open(self, *args, **opts) - self.sock = SocketProxy(self.sock) +tl = telnetlib class WriteTests(TestCase): '''The only thing that write does is replace each tl.IAC for tl.IAC+tl.IAC''' - def setUp(self): - self.evt = threading.Event() - self.test_done = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=( - self.evt, self.sock, self.dataq, self.test_done)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - - def tearDown(self): - self.test_done.set() - self.evt.wait() - self.thread.join() - - def _test_write(self, data): - self.telnet.sock._raw_sent = b'' - self.telnet.write(data) - after_write = self.telnet.sock._raw_sent - self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), - after_write) def test_write(self): - self.telnet = TelnetSockSendall() data_sample = [b'data sample without IAC', b'data sample with' + tl.IAC + b' one IAC', b'a few' + tl.IAC + tl.IAC + b' iacs' + tl.IAC, tl.IAC, b''] - self.telnet.open(HOST, self.port) - for d in data_sample: - self.dataq.put([b'']) - self._test_write(d) - self.telnet.close() - -tl = telnetlib - -class TelnetDebuglevel(tl.Telnet): - ''' Telnet-alike that captures messages written to stdout when - debuglevel > 0 - ''' - _messages = '' - def msg(self, msg, *args): - orig_stdout = sys.stdout - sys.stdout = fake_stdout = io.StringIO() - tl.Telnet.msg(self, msg, *args) - self._messages += fake_stdout.getvalue() - sys.stdout = orig_stdout - return + for data in data_sample: + telnet = test_telnet() + telnet.write(data) + written = b''.join(telnet.sock.writes) + self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), written) class OptionTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown # RFC 854 commands cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] def _test_command(self, data): """ helper for testing IAC + cmd """ - self.setUp() - self.dataq.put(data) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(data) + data_len = len(b''.join(data)) nego = nego_collector() telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -401,24 +286,16 @@ self.assertTrue(len(cmd) > 0) # we expect at least one command self.assertTrue(cmd[:1] in self.cmds) self.assertEqual(cmd[1:2], tl.NOOPT) - self.assertEqual(len(b''.join(data[:-1])), len(txt + cmd)) + self.assertEqual(data_len, len(txt + cmd)) nego.sb_getter = None # break the nego => telnet cycle - self.tearDown() def test_IAC_commands(self): - # reset our setup - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.tearDown() - for cmd in self.cmds: - self._test_command([tl.IAC, cmd, EOF_sigil]) - self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100, EOF_sigil]) - self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10, EOF_sigil]) + self._test_command([tl.IAC, cmd]) + self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100]) + self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10]) # all at once - self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) - self.assertEqual(b'', telnet.read_sb_data()) + self._test_command([tl.IAC + cmd for (cmd) in self.cmds]) def test_SB_commands(self): # RFC 855, subnegotiations portion @@ -427,11 +304,8 @@ tl.IAC + tl.SB + tl.IAC + tl.IAC + b'aa' + tl.IAC + tl.SE, tl.IAC + tl.SB + b'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, tl.IAC + tl.SB + b'cc' + tl.IAC + tl.IAC + b'dd' + tl.IAC + tl.SE, - EOF_sigil, ] - self.dataq.put(send) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(send) nego = nego_collector(telnet.read_sb_data) telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -441,19 +315,6 @@ self.assertEqual(b'', telnet.read_sb_data()) nego.sb_getter = None # break the nego => telnet cycle - def _test_debuglevel(self, data, expected_msg): - """ helper for testing debuglevel messages """ - self.setUp() - self.dataq.put(data + [EOF_sigil]) - telnet = TelnetDebuglevel(HOST, self.port) - telnet.set_debuglevel(1) - self.dataq.join() - txt = telnet.read_all() - self.assertTrue(expected_msg in telnet._messages, - msg=(telnet._messages, expected_msg)) - telnet.close() - self.tearDown() - def test_debuglevel_reads(self): # test all the various places that self.msg(...) is called given_a_expect_b = [ @@ -467,21 +328,18 @@ (tl.IAC + tl.WONT + bytes([1]), ": IAC WONT 1\n"), ] for a, b in given_a_expect_b: - self._test_debuglevel([a, EOF_sigil], b) + telnet = test_telnet([a]) + telnet.set_debuglevel(1) + txt = telnet.read_all() + self.assertTrue(b in telnet._messages) return def test_debuglevel_write(self): - self.setUp() - telnet = TelnetDebuglevel(HOST, self.port) + telnet = test_telnet() telnet.set_debuglevel(1) - self.dataq.put([b'', EOF_sigil]) - self.dataq.join() telnet.write(b'xxx') expected = "send b'xxx'\n" - self.assertTrue(expected in telnet._messages, - msg=(telnet._messages, expected)) - telnet.close() - self.tearDown() + self.assertTrue(expected in telnet._messages) def test_main(verbose=None): support.run_unittest(GeneralTests, ReadTests, WriteTests, OptionTests) From python-checkins at python.org Fri Nov 6 20:40:07 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 06 Nov 2009 19:40:07 -0000 Subject: [Python-checkins] r76134 - in sandbox/trunk/newgil: Lib/_threading_local.py Lib/importlib/test/source/util.py Lib/test/test_kqueue.py Lib/test/test_telnetlib.py Lib/threading.py Misc/ACKS Misc/NEWS Modules/selectmodule.c Message-ID: Author: antoine.pitrou Date: Fri Nov 6 20:40:06 2009 New Revision: 76134 Log: Merged revisions 76111,76113-76114,76119,76124,76133 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76111 | antoine.pitrou | 2009-11-04 22:10:38 +0100 (mer., 04 nov. 2009) | 12 lines Merged revisions 76108 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76108 | antoine.pitrou | 2009-11-04 20:25:14 +0100 (mer., 04 nov. 2009) | 6 lines Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent objects on 64-bit systems. Patch by Michael Broghton. I will revert this checkin if it causes problems on our BSD buildbots. ........ ................ r76113 | brett.cannon | 2009-11-05 02:17:22 +0100 (jeu., 05 nov. 2009) | 3 lines importlib.test.source.util referenced variables in the 'finally' part of a try/finally which may not have been set. ................ r76114 | brett.cannon | 2009-11-05 02:26:57 +0100 (jeu., 05 nov. 2009) | 6 lines Use tempfile.mkdtemp() instead of tempfile.tempdir for where importlib places source files for tests. Allows for concurrent execution of the tests by preventing various executions from trampling each other. Closes issue #7248. ................ r76119 | antoine.pitrou | 2009-11-05 14:49:14 +0100 (jeu., 05 nov. 2009) | 10 lines Merged revisions 76117 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76117 | antoine.pitrou | 2009-11-05 14:42:29 +0100 (jeu., 05 nov. 2009) | 5 lines Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. ........ ................ r76124 | r.david.murray | 2009-11-05 18:49:10 +0100 (jeu., 05 nov. 2009) | 9 lines Blocked revisions 76116 via svnmerge ........ r76116 | r.david.murray | 2009-11-04 20:50:56 -0500 (Wed, 04 Nov 2009) | 3 lines Increase the timeout in the bsddb3 replication test to allow the test time to complete on slow buildbots. See issue 6462. ........ ................ r76133 | jack.diederich | 2009-11-06 18:20:42 +0100 (ven., 06 nov. 2009) | 3 lines - issue #6748 intermittent test failures from sockets - telnetlib tests now use mock sockets for most tests ................ Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Lib/_threading_local.py sandbox/trunk/newgil/Lib/importlib/test/source/util.py sandbox/trunk/newgil/Lib/test/test_kqueue.py sandbox/trunk/newgil/Lib/test/test_telnetlib.py sandbox/trunk/newgil/Lib/threading.py sandbox/trunk/newgil/Misc/ACKS sandbox/trunk/newgil/Misc/NEWS sandbox/trunk/newgil/Modules/selectmodule.c Modified: sandbox/trunk/newgil/Lib/_threading_local.py ============================================================================== --- sandbox/trunk/newgil/Lib/_threading_local.py (original) +++ sandbox/trunk/newgil/Lib/_threading_local.py Fri Nov 6 20:40:06 2009 @@ -217,10 +217,12 @@ key = object.__getattribute__(self, '_local__key') try: - threads = list(threading.enumerate()) + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() except: - # If enumerate fails, as it seems to do during - # shutdown, we'll skip cleanup under the assumption + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up. return Modified: sandbox/trunk/newgil/Lib/importlib/test/source/util.py ============================================================================== --- sandbox/trunk/newgil/Lib/importlib/test/source/util.py (original) +++ sandbox/trunk/newgil/Lib/importlib/test/source/util.py Fri Nov 6 20:40:06 2009 @@ -42,8 +42,8 @@ that contains the name passed into the context manager that caused the creation of the module. - All files are created in a temporary directory specified by - tempfile.gettempdir(). This directory is inserted at the beginning of + All files are created in a temporary directory returned by + tempfile.mkdtemp(). This directory is inserted at the beginning of sys.path. When the context manager exits all created files (source and bytecode) are explicitly deleted. @@ -55,8 +55,10 @@ source = 'attr = {0!r}' created_paths = [] mapping = {} + state_manager = None + uncache_manager = None try: - temp_dir = tempfile.gettempdir() + temp_dir = tempfile.mkdtemp() mapping['.root'] = temp_dir import_names = set() for name in names: @@ -85,13 +87,8 @@ state_manager.__enter__() yield mapping finally: - state_manager.__exit__(None, None, None) - uncache_manager.__exit__(None, None, None) - # Reverse the order for path removal to unroll directory creation. - for path in reversed(created_paths): - if file_path.endswith('.py'): - support.unlink(path) - support.unlink(path + 'c') - support.unlink(path + 'o') - else: - os.rmdir(path) + if state_manager is not None: + state_manager.__exit__(None, None, None) + if uncache_manager is not None: + uncache_manager.__exit__(None, None, None) + support.rmtree(temp_dir) Modified: sandbox/trunk/newgil/Lib/test/test_kqueue.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_kqueue.py (original) +++ sandbox/trunk/newgil/Lib/test/test_kqueue.py Fri Nov 6 20:40:06 2009 @@ -71,6 +71,17 @@ self.assertEqual(ev, ev) self.assertNotEqual(ev, other) + bignum = sys.maxsize * 2 + 1 + ev = select.kevent(bignum, 1, 2, 3, sys.maxsize, bignum) + self.assertEqual(ev.ident, bignum) + self.assertEqual(ev.filter, 1) + self.assertEqual(ev.flags, 2) + self.assertEqual(ev.fflags, 3) + self.assertEqual(ev.data, sys.maxsize) + self.assertEqual(ev.udata, bignum) + self.assertEqual(ev, ev) + self.assertNotEqual(ev, other) + def test_queue_event(self): serverSocket = socket.socket() serverSocket.bind(('127.0.0.1', 0)) Modified: sandbox/trunk/newgil/Lib/test/test_telnetlib.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_telnetlib.py (original) +++ sandbox/trunk/newgil/Lib/test/test_telnetlib.py Fri Nov 6 20:40:06 2009 @@ -1,48 +1,23 @@ import socket +import select import threading import telnetlib import time -import queue -import sys -import io +import contextlib from unittest import TestCase from test import support HOST = support.HOST -EOF_sigil = object() -def server(evt, serv, dataq=None, test_done=None): - """ Open a tcp server in four steps - 1) set evt to true to let the parent know we are ready - 2) [optional] if is not False, write the list of data from dataq.get() - to the socket. - 3) [optional] if test_done is not None, it's an event; wait - for parent to set test_done before closing connection - 4) set evt to true to let the parent know we're done - """ +def server(evt, serv): serv.listen(5) evt.set() try: conn, addr = serv.accept() - if dataq: - data = b'' - new_data = dataq.get(True, 0.5) - dataq.task_done() - for item in new_data: - if item == EOF_sigil: - break - if type(item) in [int, float]: - time.sleep(item) - else: - data += item - written = conn.send(data) - data = data[written:] except socket.timeout: pass finally: - if test_done is not None: - test_done.wait() serv.close() evt.set() @@ -100,163 +75,159 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() -def _read_setUp(self): - self.evt = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - -def _read_tearDown(self): - self.evt.wait() - self.thread.join() +class SocketStub(object): + ''' a socket proxy that re-defines sendall() ''' + def __init__(self, reads=[]): + self.reads = reads + self.writes = [] + self.block = False + def sendall(self, data): + self.writes.append(data) + def recv(self, size): + out = b'' + while self.reads and len(out) < size: + out += self.reads.pop(0) + if len(out) > size: + self.reads.insert(0, out[size:]) + out = out[:size] + return out + +class TelnetAlike(telnetlib.Telnet): + def fileno(self): + raise NotImplementedError() + def close(self): pass + def sock_avail(self): + return (not self.sock.block) + def msg(self, msg, *args): + with support.captured_stdout() as out: + telnetlib.Telnet.msg(self, msg, *args) + self._messages += out.getvalue() + return + +def new_select(*s_args): + block = False + for l in s_args: + for fob in l: + if isinstance(fob, TelnetAlike): + block = fob.sock.block + if block: + return [[], [], []] + else: + return s_args + + at contextlib.contextmanager +def test_socket(reads): + def new_conn(*ignored): + return SocketStub(reads) + try: + old_conn = socket.create_connection + socket.create_connection = new_conn + yield None + finally: + socket.create_connection = old_conn + return + +def test_telnet(reads=[], cls=TelnetAlike): + ''' return a telnetlib.Telnet object that uses a SocketStub with + reads queued up to be read ''' + for x in reads: + assert type(x) is bytes, x + with test_socket(reads): + telnet = cls('dummy', 0) + telnet._messages = '' # debuglevel output + return telnet class ReadTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown + def setUp(self): + self.old_select = select.select + select.select = new_select + def tearDown(self): + select.select = self.old_select - # use a similar approach to testing timeouts as test_timeout.py - # these will never pass 100% but make the fuzz big enough that it is rare - block_long = 0.6 - block_short = 0.3 - def test_read_until_A(self): + def test_read_until(self): """ - read_until(expected, [timeout]) - Read until the expected string has been seen, or a timeout is - hit (default is no timeout); may block. + read_until(expected, timeout=None) + test the blocking version of read_util """ - want = [b'x' * 10, b'match', b'y' * 10, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = [b'xxxmatchyyy'] + telnet = test_telnet(want) data = telnet.read_until(b'match') - self.assertEqual(data, b''.join(want[:-2])) + self.assertEqual(data, b'xxxmatch', msg=(telnet.cookedq, telnet.rawq, telnet.sock.reads)) - def test_read_until_B(self): - # test the timeout - it does NOT raise socket.timeout - want = [b'hello', self.block_long, b'not seen', EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_until(b'not seen', self.block_short) - self.assertEqual(data, want[0]) - self.assertEqual(telnet.read_all(), b'not seen') + reads = [b'x' * 50, b'match', b'y' * 50] + expect = b''.join(reads[:-1]) + telnet = test_telnet(reads) + data = telnet.read_until(b'match') + self.assertEqual(data, expect) - def test_read_all_A(self): + + def test_read_all(self): """ read_all() Read all data until EOF; may block. """ - want = [b'x' * 500, b'y' * 500, b'z' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + reads = [b'x' * 500, b'y' * 500, b'z' * 500] + expect = b''.join(reads) + telnet = test_telnet(reads) data = telnet.read_all() - self.assertEqual(data, b''.join(want[:-1])) + self.assertEqual(data, expect) return - def _test_blocking(self, func): - self.dataq.put([self.block_long, EOF_sigil]) - self.dataq.join() - start = time.time() - data = func() - self.assertTrue(self.block_short <= time.time() - start) - - def test_read_all_B(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) - - def test_read_all_C(self): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - telnet.read_all() - telnet.read_all() # shouldn't raise - - def test_read_some_A(self): + def test_read_some(self): """ read_some() Read at least one byte or EOF; may block. """ # test 'at least one byte' - want = [b'x' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_all() + telnet = test_telnet([b'x' * 500]) + data = telnet.read_some() self.assertTrue(len(data) >= 1) - - def test_read_some_B(self): # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.assertEqual(b'', telnet.read_some()) - - def test_read_some_C(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) + telnet = test_telnet() + data = telnet.read_some() + self.assertEqual(b'', data) - def _test_read_any_eager_A(self, func_name): + def _read_eager(self, func_name): """ - read_very_eager() + read_*_eager() Read all data available already queued or on the socket, without blocking. """ - want = [self.block_long, b'x' * 100, b'y' * 100, EOF_sigil] - expects = want[1] + want[2] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = b'x' * 100 + telnet = test_telnet([want]) func = getattr(telnet, func_name) + telnet.sock.block = True + self.assertEqual(b'', func()) + telnet.sock.block = False data = b'' while True: try: data += func() - self.assertTrue(expects.startswith(data)) except EOFError: break - self.assertEqual(expects, data) - - def _test_read_any_eager_B(self, func_name): - # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - func = getattr(telnet, func_name) - self.assertRaises(EOFError, func) + self.assertEqual(data, want) - # read_eager and read_very_eager make the same gaurantees - # (they behave differently but we only test the gaurantees) - def test_read_very_eager_A(self): - self._test_read_any_eager_A('read_very_eager') - def test_read_very_eager_B(self): - self._test_read_any_eager_B('read_very_eager') - def test_read_eager_A(self): - self._test_read_any_eager_A('read_eager') - def test_read_eager_B(self): - self._test_read_any_eager_B('read_eager') - # NB -- we need to test the IAC block which is mentioned in the docstring - # but not in the module docs - - def _test_read_any_lazy_B(self, func_name): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - func = getattr(telnet, func_name) - telnet.fill_rawq() - self.assertRaises(EOFError, func) - - def test_read_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) + def test_read_eager(self): + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + self._read_eager('read_eager') + self._read_eager('read_very_eager') + # NB -- we need to test the IAC block which is mentioned in the + # docstring but not in the module docs + + def read_very_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) + self.assertEqual(b'', telnet.read_very_lazy()) + while telnet.sock.reads: + telnet.fill_rawq() + data = telnet.read_very_lazy() + self.assertEqual(want, data) + self.assertRaises(EOFError, telnet.read_very_lazy) + + def test_read_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) self.assertEqual(b'', telnet.read_lazy()) data = b'' while True: @@ -267,35 +238,8 @@ telnet.fill_rawq() except EOFError: break - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_lazy_B(self): - self._test_read_any_lazy_B('read_lazy') - - def test_read_very_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - self.assertEqual(b'', telnet.read_very_lazy()) - data = b'' - while True: - try: - read_data = telnet.read_very_lazy() - except EOFError: - break - data += read_data - if not read_data: - telnet.fill_rawq() - self.assertEqual(b'', telnet.cookedq) - telnet.process_rawq() - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_very_lazy_B(self): - self._test_read_any_lazy_B('read_very_lazy') + self.assertTrue(want.startswith(data)) + self.assertEqual(data, want) class nego_collector(object): def __init__(self, sb_getter=None): @@ -309,91 +253,32 @@ sb_data = self.sb_getter() self.sb_seen += sb_data -class SocketProxy(object): - ''' a socket proxy that re-defines sendall() ''' - def __init__(self, real_sock): - self.socket = real_sock - self._raw_sent = b'' - def __getattr__(self, k): - return getattr(self.socket, k) - def sendall(self, data): - self._raw_sent += data - self.socket.sendall(data) - -class TelnetSockSendall(telnetlib.Telnet): - def open(self, *args, **opts): - telnetlib.Telnet.open(self, *args, **opts) - self.sock = SocketProxy(self.sock) +tl = telnetlib class WriteTests(TestCase): '''The only thing that write does is replace each tl.IAC for tl.IAC+tl.IAC''' - def setUp(self): - self.evt = threading.Event() - self.test_done = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=( - self.evt, self.sock, self.dataq, self.test_done)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - - def tearDown(self): - self.test_done.set() - self.evt.wait() - self.thread.join() - - def _test_write(self, data): - self.telnet.sock._raw_sent = b'' - self.telnet.write(data) - after_write = self.telnet.sock._raw_sent - self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), - after_write) def test_write(self): - self.telnet = TelnetSockSendall() data_sample = [b'data sample without IAC', b'data sample with' + tl.IAC + b' one IAC', b'a few' + tl.IAC + tl.IAC + b' iacs' + tl.IAC, tl.IAC, b''] - self.telnet.open(HOST, self.port) - for d in data_sample: - self.dataq.put([b'']) - self._test_write(d) - self.telnet.close() - -tl = telnetlib - -class TelnetDebuglevel(tl.Telnet): - ''' Telnet-alike that captures messages written to stdout when - debuglevel > 0 - ''' - _messages = '' - def msg(self, msg, *args): - orig_stdout = sys.stdout - sys.stdout = fake_stdout = io.StringIO() - tl.Telnet.msg(self, msg, *args) - self._messages += fake_stdout.getvalue() - sys.stdout = orig_stdout - return + for data in data_sample: + telnet = test_telnet() + telnet.write(data) + written = b''.join(telnet.sock.writes) + self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), written) class OptionTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown # RFC 854 commands cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] def _test_command(self, data): """ helper for testing IAC + cmd """ - self.setUp() - self.dataq.put(data) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(data) + data_len = len(b''.join(data)) nego = nego_collector() telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -401,24 +286,16 @@ self.assertTrue(len(cmd) > 0) # we expect at least one command self.assertTrue(cmd[:1] in self.cmds) self.assertEqual(cmd[1:2], tl.NOOPT) - self.assertEqual(len(b''.join(data[:-1])), len(txt + cmd)) + self.assertEqual(data_len, len(txt + cmd)) nego.sb_getter = None # break the nego => telnet cycle - self.tearDown() def test_IAC_commands(self): - # reset our setup - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.tearDown() - for cmd in self.cmds: - self._test_command([tl.IAC, cmd, EOF_sigil]) - self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100, EOF_sigil]) - self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10, EOF_sigil]) + self._test_command([tl.IAC, cmd]) + self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100]) + self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10]) # all at once - self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) - self.assertEqual(b'', telnet.read_sb_data()) + self._test_command([tl.IAC + cmd for (cmd) in self.cmds]) def test_SB_commands(self): # RFC 855, subnegotiations portion @@ -427,11 +304,8 @@ tl.IAC + tl.SB + tl.IAC + tl.IAC + b'aa' + tl.IAC + tl.SE, tl.IAC + tl.SB + b'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, tl.IAC + tl.SB + b'cc' + tl.IAC + tl.IAC + b'dd' + tl.IAC + tl.SE, - EOF_sigil, ] - self.dataq.put(send) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(send) nego = nego_collector(telnet.read_sb_data) telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -441,19 +315,6 @@ self.assertEqual(b'', telnet.read_sb_data()) nego.sb_getter = None # break the nego => telnet cycle - def _test_debuglevel(self, data, expected_msg): - """ helper for testing debuglevel messages """ - self.setUp() - self.dataq.put(data + [EOF_sigil]) - telnet = TelnetDebuglevel(HOST, self.port) - telnet.set_debuglevel(1) - self.dataq.join() - txt = telnet.read_all() - self.assertTrue(expected_msg in telnet._messages, - msg=(telnet._messages, expected_msg)) - telnet.close() - self.tearDown() - def test_debuglevel_reads(self): # test all the various places that self.msg(...) is called given_a_expect_b = [ @@ -467,21 +328,18 @@ (tl.IAC + tl.WONT + bytes([1]), ": IAC WONT 1\n"), ] for a, b in given_a_expect_b: - self._test_debuglevel([a, EOF_sigil], b) + telnet = test_telnet([a]) + telnet.set_debuglevel(1) + txt = telnet.read_all() + self.assertTrue(b in telnet._messages) return def test_debuglevel_write(self): - self.setUp() - telnet = TelnetDebuglevel(HOST, self.port) + telnet = test_telnet() telnet.set_debuglevel(1) - self.dataq.put([b'', EOF_sigil]) - self.dataq.join() telnet.write(b'xxx') expected = "send b'xxx'\n" - self.assertTrue(expected in telnet._messages, - msg=(telnet._messages, expected)) - telnet.close() - self.tearDown() + self.assertTrue(expected in telnet._messages) def test_main(verbose=None): support.run_unittest(GeneralTests, ReadTests, WriteTests, OptionTests) Modified: sandbox/trunk/newgil/Lib/threading.py ============================================================================== --- sandbox/trunk/newgil/Lib/threading.py (original) +++ sandbox/trunk/newgil/Lib/threading.py Fri Nov 6 20:40:06 2009 @@ -798,6 +798,10 @@ activeCount = active_count +def _enumerate(): + # Same as enumerate(), but without the lock. Internal use only. + return list(_active.values()) + list(_limbo.values()) + def enumerate(): with _active_limbo_lock: return list(_active.values()) + list(_limbo.values()) Modified: sandbox/trunk/newgil/Misc/ACKS ============================================================================== --- sandbox/trunk/newgil/Misc/ACKS (original) +++ sandbox/trunk/newgil/Misc/ACKS Fri Nov 6 20:40:06 2009 @@ -95,6 +95,7 @@ Dave Brennan Tom Bridgman Richard Brodie +Michael Broghton Daniel Brotsky Jean Brouwers Gary S. Brown Modified: sandbox/trunk/newgil/Misc/NEWS ============================================================================== --- sandbox/trunk/newgil/Misc/NEWS (original) +++ sandbox/trunk/newgil/Misc/NEWS Fri Nov 6 20:40:06 2009 @@ -123,6 +123,12 @@ Library ------- +- Issue #7264: Fix a possible deadlock when deallocating thread-local objects + which are part of a reference cycle. + +- Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent + objects on 64-bit systems. Patch by Michael Broghton. + - Issue #6896: mailbox.Maildir now invalidates its internal cache each time a modification is done through it. This fixes inconsistencies and test failures on systems with slightly bogus mtime behaviour. @@ -351,6 +357,14 @@ Tests ----- +- Issue #7248 (part 2): Use a unique temporary directory for importlib source + tests instead of tempfile.tempdir. This prevents the tests from sharing state + between concurrent executions on the same system. + +- Issue #7248: In importlib.test.source.util a try/finally block did not make + sure that some referenced objects actually were created in the block before + calling methods on the object. + - Issue #7222: Make thread "reaping" more reliable so that reference leak-chasing test runs give sensible results. The previous method of reaping threads could return successfully while some Thread objects were Modified: sandbox/trunk/newgil/Modules/selectmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/selectmodule.c (original) +++ sandbox/trunk/newgil/Modules/selectmodule.c Fri Nov 6 20:40:06 2009 @@ -1199,6 +1199,30 @@ #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type)) +#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) +# error uintptr_t does not match void *! +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) +# define T_UINTPTRT T_ULONGLONG +# define T_INTPTRT T_LONGLONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong +# define UINTPTRT_FMT_UNIT "K" +# define INTPTRT_FMT_UNIT "L" +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) +# define T_UINTPTRT T_ULONG +# define T_INTPTRT T_LONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "k" +# define INTPTRT_FMT_UNIT "l" +#elif (SIZEOF_UINTPTR_T == SIZEOF_INT) +# define T_UINTPTRT T_UINT +# define T_INTPTRT T_INT +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "I" +# define INTPTRT_FMT_UNIT "i" +#else +# error uintptr_t does not match int, long, or long long! +#endif + /* Unfortunately, we can't store python objects in udata, because * kevents in the kernel can be removed without warning, which would * forever lose the refcount on the object stored with it. @@ -1206,12 +1230,12 @@ #define KQ_OFF(x) offsetof(kqueue_event_Object, x) static struct PyMemberDef kqueue_event_members[] = { - {"ident", T_UINT, KQ_OFF(e.ident)}, + {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, {"filter", T_SHORT, KQ_OFF(e.filter)}, {"flags", T_USHORT, KQ_OFF(e.flags)}, {"fflags", T_UINT, KQ_OFF(e.fflags)}, - {"data", T_INT, KQ_OFF(e.data)}, - {"udata", T_INT, KQ_OFF(e.udata)}, + {"data", T_INTPTRT, KQ_OFF(e.data)}, + {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, {NULL} /* Sentinel */ }; #undef KQ_OFF @@ -1222,11 +1246,11 @@ char buf[1024]; PyOS_snprintf( buf, sizeof(buf), - "", - (unsigned long)(s->e.ident), s->e.filter, s->e.flags, - s->e.fflags, (long)(s->e.data), s->e.udata); - return PyBytes_FromString(buf); + "", + (size_t)(s->e.ident), s->e.filter, s->e.flags, + s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata); + return PyUnicode_FromString(buf); } static int @@ -1235,17 +1259,23 @@ PyObject *pfd; static char *kwlist[] = {"ident", "filter", "flags", "fflags", "data", "udata", NULL}; + static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, &pfd, &(self->e.filter), &(self->e.flags), &(self->e.fflags), &(self->e.data), &(self->e.udata))) { return -1; } - self->e.ident = PyObject_AsFileDescriptor(pfd); - if (self->e.ident == -1) { + if (PyLong_Check(pfd)) { + self->e.ident = PyLong_AsUintptr_t(pfd); + } + else { + self->e.ident = PyObject_AsFileDescriptor(pfd); + } + if (PyErr_Occurred()) { return -1; } return 0; @@ -1255,7 +1285,7 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, int op) { - int result = 0; + Py_intptr_t result = 0; if (!kqueue_event_Check(o)) { if (op == Py_EQ || op == Py_NE) { @@ -1298,7 +1328,7 @@ result = (result > 0); break; } - return PyBool_FromLong(result); + return PyBool_FromLong((long)result); } static PyTypeObject kqueue_event_Type = { From python-checkins at python.org Fri Nov 6 21:00:13 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 06 Nov 2009 20:00:13 -0000 Subject: [Python-checkins] r76135 - in sandbox/trunk/newgil: Include/ceval.h Python/ceval_gil.h Python/sysmodule.c Message-ID: Author: antoine.pitrou Date: Fri Nov 6 21:00:13 2009 New Revision: 76135 Log: Store the interval as microseconds. The Python API still uses seconds though. Modified: sandbox/trunk/newgil/Include/ceval.h sandbox/trunk/newgil/Python/ceval_gil.h sandbox/trunk/newgil/Python/sysmodule.c Modified: sandbox/trunk/newgil/Include/ceval.h ============================================================================== --- sandbox/trunk/newgil/Include/ceval.h (original) +++ sandbox/trunk/newgil/Include/ceval.h Fri Nov 6 21:00:13 2009 @@ -171,8 +171,8 @@ PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReInitThreads(void); -PyAPI_FUNC(void) _PyEval_SetSwitchInterval(double seconds); -PyAPI_FUNC(double) _PyEval_GetSwitchInterval(void); +PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); +PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); #define Py_BEGIN_ALLOW_THREADS { \ PyThreadState *_save; \ Modified: sandbox/trunk/newgil/Python/ceval_gil.h ============================================================================== --- sandbox/trunk/newgil/Python/ceval_gil.h (original) +++ sandbox/trunk/newgil/Python/ceval_gil.h Fri Nov 6 21:00:13 2009 @@ -8,10 +8,10 @@ /* First some general settings */ -/* milliseconds (the public API uses seconds, though) */ -#define DEFAULT_INTERVAL 5 -static double gil_interval = DEFAULT_INTERVAL; -#define INTERVAL (gil_interval >= 1.0 ? gil_interval : 1.0) +/* microseconds (the Python API uses seconds, though) */ +#define DEFAULT_INTERVAL 5000 +static unsigned long gil_interval = DEFAULT_INTERVAL; +#define INTERVAL (gil_interval >= 1 ? gil_interval : 1) /* Enable if you want to force the switching of threads at least every `gil_interval` */ #undef FORCE_SWITCHING @@ -77,9 +77,9 @@ #include -#define ADD_MILLISECONDS(tv, interval) \ +#define ADD_MICROSECONDS(tv, interval) \ do { \ - tv.tv_usec += (long) interval * 1000; \ + tv.tv_usec += (long) interval; \ tv.tv_sec += tv.tv_usec / 1000000; \ tv.tv_usec %= 1000000; \ } while (0) @@ -113,14 +113,14 @@ #define COND_WAIT(cond, mut) \ if (pthread_cond_wait(&cond, &mut)) { \ Py_FatalError("pthread_cond_wait(" #cond ") failed"); }; -#define COND_TIMED_WAIT(cond, mut, milliseconds, timeout_result) \ +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ { \ int r; \ struct timespec ts; \ struct timeval deadline; \ \ GETTIMEOFDAY(&deadline); \ - ADD_MILLISECONDS(deadline, milliseconds); \ + ADD_MICROSECONDS(deadline, microseconds); \ ts.tv_sec = deadline.tv_sec; \ ts.tv_nsec = deadline.tv_usec * 1000; \ \ @@ -175,12 +175,12 @@ if (r != WAIT_OBJECT_0) \ Py_FatalError("WaitForSingleObject(" #cond ") failed"); \ } -#define COND_TIMED_WAIT(cond, mut, milliseconds, timeout_result) \ +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ { \ DWORD r; \ HANDLE objects[2] = { cond, mut }; \ MUTEX_UNLOCK(mut); \ - r = WaitForMultipleObjects(2, objects, TRUE, milliseconds); \ + r = WaitForMultipleObjects(2, objects, TRUE, microseconds / 1000); \ if (r == WAIT_TIMEOUT) { \ MUTEX_LOCK(mut); \ timeout_result = 1; \ @@ -404,14 +404,12 @@ #endif } -void _PyEval_SetSwitchInterval(double seconds) +void _PyEval_SetSwitchInterval(unsigned long microseconds) { - if (seconds <= 0) - Py_FatalError("switch interval must be strictly positive"); - gil_interval = seconds * 1000.0; + gil_interval = microseconds; } -double _PyEval_GetSwitchInterval() +unsigned long _PyEval_GetSwitchInterval() { - return gil_interval / 1000.0; + return gil_interval; } Modified: sandbox/trunk/newgil/Python/sysmodule.c ============================================================================== --- sandbox/trunk/newgil/Python/sysmodule.c (original) +++ sandbox/trunk/newgil/Python/sysmodule.c Fri Nov 6 21:00:13 2009 @@ -489,7 +489,7 @@ "switch interval must be strictly positive"); return NULL; } - _PyEval_SetSwitchInterval(d); + _PyEval_SetSwitchInterval((unsigned long) (1e6 * d)); Py_INCREF(Py_None); return Py_None; } @@ -509,7 +509,7 @@ static PyObject * sys_getswitchinterval(PyObject *self, PyObject *args) { - return PyFloat_FromDouble(_PyEval_GetSwitchInterval()); + return PyFloat_FromDouble(1e-6 * _PyEval_GetSwitchInterval()); } PyDoc_STRVAR(getswitchinterval_doc, From python-checkins at python.org Fri Nov 6 22:15:00 2009 From: python-checkins at python.org (jack.diederich) Date: Fri, 06 Nov 2009 21:15:00 -0000 Subject: [Python-checkins] r76136 - in python/branches/release31-maint: Lib/test/test_telnetlib.py Misc/ACKS Message-ID: Author: jack.diederich Date: Fri Nov 6 22:14:59 2009 New Revision: 76136 Log: Merged revisions 74638,76133 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r74638 | jack.diederich | 2009-09-03 16:37:58 -0400 (Thu, 03 Sep 2009) | 4 lines - apply issue 6582 to test all the write methods of telnetlib - add patch author to ACKS - possibly fix test timeouts on non-linux platforms ........ r76133 | jack.diederich | 2009-11-06 12:20:42 -0500 (Fri, 06 Nov 2009) | 3 lines - issue #6748 intermittent test failures from sockets - telnetlib tests now use mock sockets for most tests ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_telnetlib.py python/branches/release31-maint/Misc/ACKS Modified: python/branches/release31-maint/Lib/test/test_telnetlib.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_telnetlib.py (original) +++ python/branches/release31-maint/Lib/test/test_telnetlib.py Fri Nov 6 22:14:59 2009 @@ -1,41 +1,20 @@ import socket +import select import threading import telnetlib import time -import queue -import sys -import io +import contextlib from unittest import TestCase from test import support HOST = support.HOST -EOF_sigil = object() -def server(evt, serv, dataq=None): - """ Open a tcp server in three steps - 1) set evt to true to let the parent know we are ready - 2) [optional] if is not False, write the list of data from dataq.get() - to the socket. - 3) set evt to true to let the parent know we're done - """ +def server(evt, serv): serv.listen(5) evt.set() try: conn, addr = serv.accept() - if dataq: - data = b'' - new_data = dataq.get(True, 0.5) - dataq.task_done() - for item in new_data: - if item == EOF_sigil: - break - if type(item) in [int, float]: - time.sleep(item) - else: - data += item - written = conn.send(data) - data = data[written:] except socket.timeout: pass finally: @@ -96,163 +75,159 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() -def _read_setUp(self): - self.evt = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - -def _read_tearDown(self): - self.evt.wait() - self.thread.join() +class SocketStub(object): + ''' a socket proxy that re-defines sendall() ''' + def __init__(self, reads=[]): + self.reads = reads + self.writes = [] + self.block = False + def sendall(self, data): + self.writes.append(data) + def recv(self, size): + out = b'' + while self.reads and len(out) < size: + out += self.reads.pop(0) + if len(out) > size: + self.reads.insert(0, out[size:]) + out = out[:size] + return out + +class TelnetAlike(telnetlib.Telnet): + def fileno(self): + raise NotImplementedError() + def close(self): pass + def sock_avail(self): + return (not self.sock.block) + def msg(self, msg, *args): + with support.captured_stdout() as out: + telnetlib.Telnet.msg(self, msg, *args) + self._messages += out.getvalue() + return + +def new_select(*s_args): + block = False + for l in s_args: + for fob in l: + if isinstance(fob, TelnetAlike): + block = fob.sock.block + if block: + return [[], [], []] + else: + return s_args + + at contextlib.contextmanager +def test_socket(reads): + def new_conn(*ignored): + return SocketStub(reads) + try: + old_conn = socket.create_connection + socket.create_connection = new_conn + yield None + finally: + socket.create_connection = old_conn + return + +def test_telnet(reads=[], cls=TelnetAlike): + ''' return a telnetlib.Telnet object that uses a SocketStub with + reads queued up to be read ''' + for x in reads: + assert type(x) is bytes, x + with test_socket(reads): + telnet = cls('dummy', 0) + telnet._messages = '' # debuglevel output + return telnet class ReadTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown + def setUp(self): + self.old_select = select.select + select.select = new_select + def tearDown(self): + select.select = self.old_select - # use a similar approach to testing timeouts as test_timeout.py - # these will never pass 100% but make the fuzz big enough that it is rare - block_long = 0.6 - block_short = 0.3 - def test_read_until_A(self): + def test_read_until(self): """ - read_until(expected, [timeout]) - Read until the expected string has been seen, or a timeout is - hit (default is no timeout); may block. + read_until(expected, timeout=None) + test the blocking version of read_util """ - want = [b'x' * 10, b'match', b'y' * 10, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = [b'xxxmatchyyy'] + telnet = test_telnet(want) data = telnet.read_until(b'match') - self.assertEqual(data, b''.join(want[:-2])) + self.assertEqual(data, b'xxxmatch', msg=(telnet.cookedq, telnet.rawq, telnet.sock.reads)) - def test_read_until_B(self): - # test the timeout - it does NOT raise socket.timeout - want = [b'hello', self.block_long, b'not seen', EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_until(b'not seen', self.block_short) - self.assertEqual(data, want[0]) - self.assertEqual(telnet.read_all(), b'not seen') + reads = [b'x' * 50, b'match', b'y' * 50] + expect = b''.join(reads[:-1]) + telnet = test_telnet(reads) + data = telnet.read_until(b'match') + self.assertEqual(data, expect) - def test_read_all_A(self): + + def test_read_all(self): """ read_all() Read all data until EOF; may block. """ - want = [b'x' * 500, b'y' * 500, b'z' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + reads = [b'x' * 500, b'y' * 500, b'z' * 500] + expect = b''.join(reads) + telnet = test_telnet(reads) data = telnet.read_all() - self.assertEqual(data, b''.join(want[:-1])) + self.assertEqual(data, expect) return - def _test_blocking(self, func): - self.dataq.put([self.block_long, EOF_sigil]) - self.dataq.join() - start = time.time() - data = func() - self.assertTrue(self.block_short <= time.time() - start) - - def test_read_all_B(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) - - def test_read_all_C(self): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - telnet.read_all() - telnet.read_all() # shouldn't raise - - def test_read_some_A(self): + def test_read_some(self): """ read_some() Read at least one byte or EOF; may block. """ # test 'at least one byte' - want = [b'x' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_all() + telnet = test_telnet([b'x' * 500]) + data = telnet.read_some() self.assertTrue(len(data) >= 1) - - def test_read_some_B(self): # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.assertEqual(b'', telnet.read_some()) + telnet = test_telnet() + data = telnet.read_some() + self.assertEqual(b'', data) - def test_read_some_C(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) - - def _test_read_any_eager_A(self, func_name): + def _read_eager(self, func_name): """ - read_very_eager() + read_*_eager() Read all data available already queued or on the socket, without blocking. """ - want = [self.block_long, b'x' * 100, b'y' * 100, EOF_sigil] - expects = want[1] + want[2] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = b'x' * 100 + telnet = test_telnet([want]) func = getattr(telnet, func_name) + telnet.sock.block = True + self.assertEqual(b'', func()) + telnet.sock.block = False data = b'' while True: try: data += func() - self.assertTrue(expects.startswith(data)) except EOFError: break - self.assertEqual(expects, data) - - def _test_read_any_eager_B(self, func_name): - # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - func = getattr(telnet, func_name) - self.assertRaises(EOFError, func) - - # read_eager and read_very_eager make the same gaurantees - # (they behave differently but we only test the gaurantees) - def test_read_very_eager_A(self): - self._test_read_any_eager_A('read_very_eager') - def test_read_very_eager_B(self): - self._test_read_any_eager_B('read_very_eager') - def test_read_eager_A(self): - self._test_read_any_eager_A('read_eager') - def test_read_eager_B(self): - self._test_read_any_eager_B('read_eager') - # NB -- we need to test the IAC block which is mentioned in the docstring - # but not in the module docs + self.assertEqual(data, want) - def _test_read_any_lazy_B(self, func_name): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - func = getattr(telnet, func_name) - telnet.fill_rawq() - self.assertRaises(EOFError, func) - - def test_read_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) + def test_read_eager(self): + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + self._read_eager('read_eager') + self._read_eager('read_very_eager') + # NB -- we need to test the IAC block which is mentioned in the + # docstring but not in the module docs + + def read_very_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) + self.assertEqual(b'', telnet.read_very_lazy()) + while telnet.sock.reads: + telnet.fill_rawq() + data = telnet.read_very_lazy() + self.assertEqual(want, data) + self.assertRaises(EOFError, telnet.read_very_lazy) + + def test_read_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) self.assertEqual(b'', telnet.read_lazy()) data = b'' while True: @@ -263,35 +238,8 @@ telnet.fill_rawq() except EOFError: break - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_lazy_B(self): - self._test_read_any_lazy_B('read_lazy') - - def test_read_very_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - self.assertEqual(b'', telnet.read_very_lazy()) - data = b'' - while True: - try: - read_data = telnet.read_very_lazy() - except EOFError: - break - data += read_data - if not read_data: - telnet.fill_rawq() - self.assertEqual(b'', telnet.cookedq) - telnet.process_rawq() - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_very_lazy_B(self): - self._test_read_any_lazy_B('read_very_lazy') + self.assertTrue(want.startswith(data)) + self.assertEqual(data, want) class nego_collector(object): def __init__(self, sb_getter=None): @@ -307,31 +255,30 @@ tl = telnetlib -class TelnetDebuglevel(tl.Telnet): - ''' Telnet-alike that captures messages written to stdout when - debuglevel > 0 - ''' - _messages = '' - def msg(self, msg, *args): - orig_stdout = sys.stdout - sys.stdout = fake_stdout = io.StringIO() - tl.Telnet.msg(self, msg, *args) - self._messages += fake_stdout.getvalue() - sys.stdout = orig_stdout - return +class WriteTests(TestCase): + '''The only thing that write does is replace each tl.IAC for + tl.IAC+tl.IAC''' + + def test_write(self): + data_sample = [b'data sample without IAC', + b'data sample with' + tl.IAC + b' one IAC', + b'a few' + tl.IAC + tl.IAC + b' iacs' + tl.IAC, + tl.IAC, + b''] + for data in data_sample: + telnet = test_telnet() + telnet.write(data) + written = b''.join(telnet.sock.writes) + self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), written) class OptionTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown # RFC 854 commands cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] def _test_command(self, data): """ helper for testing IAC + cmd """ - self.setUp() - self.dataq.put(data) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(data) + data_len = len(b''.join(data)) nego = nego_collector() telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -339,24 +286,16 @@ self.assertTrue(len(cmd) > 0) # we expect at least one command self.assertTrue(cmd[:1] in self.cmds) self.assertEqual(cmd[1:2], tl.NOOPT) - self.assertEqual(len(b''.join(data[:-1])), len(txt + cmd)) + self.assertEqual(data_len, len(txt + cmd)) nego.sb_getter = None # break the nego => telnet cycle - self.tearDown() def test_IAC_commands(self): - # reset our setup - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.tearDown() - for cmd in self.cmds: - self._test_command([tl.IAC, cmd, EOF_sigil]) - self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100, EOF_sigil]) - self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10, EOF_sigil]) + self._test_command([tl.IAC, cmd]) + self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100]) + self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10]) # all at once - self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) - self.assertEqual(b'', telnet.read_sb_data()) + self._test_command([tl.IAC + cmd for (cmd) in self.cmds]) def test_SB_commands(self): # RFC 855, subnegotiations portion @@ -365,11 +304,8 @@ tl.IAC + tl.SB + tl.IAC + tl.IAC + b'aa' + tl.IAC + tl.SE, tl.IAC + tl.SB + b'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, tl.IAC + tl.SB + b'cc' + tl.IAC + tl.IAC + b'dd' + tl.IAC + tl.SE, - EOF_sigil, ] - self.dataq.put(send) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(send) nego = nego_collector(telnet.read_sb_data) telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -379,19 +315,7 @@ self.assertEqual(b'', telnet.read_sb_data()) nego.sb_getter = None # break the nego => telnet cycle - def _test_debuglevel(self, data, expected_msg): - """ helper for testing debuglevel messages """ - self.setUp() - self.dataq.put(data) - telnet = TelnetDebuglevel(HOST, self.port) - telnet.set_debuglevel(1) - self.dataq.join() - txt = telnet.read_all() - self.assertTrue(expected_msg in telnet._messages, - msg=(telnet._messages, expected_msg)) - self.tearDown() - - def test_debuglevel(self): + def test_debuglevel_reads(self): # test all the various places that self.msg(...) is called given_a_expect_b = [ # Telnet.fill_rawq @@ -402,15 +326,23 @@ (tl.IAC + tl.DONT + bytes([1]), ": IAC DONT 1\n"), (tl.IAC + tl.WILL + bytes([1]), ": IAC WILL 1\n"), (tl.IAC + tl.WONT + bytes([1]), ": IAC WONT 1\n"), - # Telnet.write - # XXX, untested ] for a, b in given_a_expect_b: - self._test_debuglevel([a, EOF_sigil], b) + telnet = test_telnet([a]) + telnet.set_debuglevel(1) + txt = telnet.read_all() + self.assertTrue(b in telnet._messages) return + def test_debuglevel_write(self): + telnet = test_telnet() + telnet.set_debuglevel(1) + telnet.write(b'xxx') + expected = "send b'xxx'\n" + self.assertTrue(expected in telnet._messages) + def test_main(verbose=None): - support.run_unittest(GeneralTests, ReadTests, OptionTests) + support.run_unittest(GeneralTests, ReadTests, WriteTests, OptionTests) if __name__ == '__main__': test_main() Modified: python/branches/release31-maint/Misc/ACKS ============================================================================== --- python/branches/release31-maint/Misc/ACKS (original) +++ python/branches/release31-maint/Misc/ACKS Fri Nov 6 22:14:59 2009 @@ -774,6 +774,7 @@ Charles Waldman Richard Walker Larry Wall +Rodrigo Steinmuller Wanderley Greg Ward Barry Warsaw Steve Waterbury From python-checkins at python.org Fri Nov 6 23:34:35 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 06 Nov 2009 22:34:35 -0000 Subject: [Python-checkins] r76137 - in python/trunk: Lib/test/lock_tests.py Lib/test/test_thread.py Lib/test/test_threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 6 23:34:35 2009 New Revision: 76137 Log: Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. Added: python/trunk/Lib/test/lock_tests.py (contents, props changed) Modified: python/trunk/Lib/test/test_thread.py python/trunk/Lib/test/test_threading.py python/trunk/Misc/NEWS Added: python/trunk/Lib/test/lock_tests.py ============================================================================== --- (empty file) +++ python/trunk/Lib/test/lock_tests.py Fri Nov 6 23:34:35 2009 @@ -0,0 +1,533 @@ +""" +Various tests for synchronization primitives. +""" + +import sys +import time +from thread import start_new_thread, get_ident +import threading +import unittest + +from test import test_support as support + + +def _wait(): + # A crude wait/yield function not relying on synchronization primitives. + time.sleep(0.01) + +class Bunch(object): + """ + A bunch of threads. + """ + def __init__(self, f, n, wait_before_exit=False): + """ + Construct a bunch of `n` threads running the same function `f`. + If `wait_before_exit` is True, the threads won't terminate until + do_finish() is called. + """ + self.f = f + self.n = n + self.started = [] + self.finished = [] + self._can_exit = not wait_before_exit + def task(): + tid = get_ident() + self.started.append(tid) + try: + f() + finally: + self.finished.append(tid) + while not self._can_exit: + _wait() + for i in range(n): + start_new_thread(task, ()) + + def wait_for_started(self): + while len(self.started) < self.n: + _wait() + + def wait_for_finished(self): + while len(self.finished) < self.n: + _wait() + + def do_finish(self): + self._can_exit = True + + +class BaseTestCase(unittest.TestCase): + def setUp(self): + self._threads = support.threading_setup() + + def tearDown(self): + support.threading_cleanup(*self._threads) + support.reap_children() + + +class BaseLockTests(BaseTestCase): + """ + Tests for both recursive and non-recursive locks. + """ + + def test_constructor(self): + lock = self.locktype() + del lock + + def test_acquire_destroy(self): + lock = self.locktype() + lock.acquire() + del lock + + def test_acquire_release(self): + lock = self.locktype() + lock.acquire() + lock.release() + del lock + + def test_try_acquire(self): + lock = self.locktype() + self.assertTrue(lock.acquire(False)) + lock.release() + + def test_try_acquire_contended(self): + lock = self.locktype() + lock.acquire() + result = [] + def f(): + result.append(lock.acquire(False)) + Bunch(f, 1).wait_for_finished() + self.assertFalse(result[0]) + lock.release() + + def test_acquire_contended(self): + lock = self.locktype() + lock.acquire() + N = 5 + def f(): + lock.acquire() + lock.release() + + b = Bunch(f, N) + b.wait_for_started() + _wait() + self.assertEqual(len(b.finished), 0) + lock.release() + b.wait_for_finished() + self.assertEqual(len(b.finished), N) + + def test_with(self): + lock = self.locktype() + def f(): + lock.acquire() + lock.release() + def _with(err=None): + with lock: + if err is not None: + raise err + _with() + # Check the lock is unacquired + Bunch(f, 1).wait_for_finished() + self.assertRaises(TypeError, _with, TypeError) + # Check the lock is unacquired + Bunch(f, 1).wait_for_finished() + + +class LockTests(BaseLockTests): + """ + Tests for non-recursive, weak locks + (which can be acquired and released from different threads). + """ + def test_reacquire(self): + # Lock needs to be released before re-acquiring. + lock = self.locktype() + phase = [] + def f(): + lock.acquire() + phase.append(None) + lock.acquire() + phase.append(None) + start_new_thread(f, ()) + while len(phase) == 0: + _wait() + _wait() + self.assertEqual(len(phase), 1) + lock.release() + while len(phase) == 1: + _wait() + self.assertEqual(len(phase), 2) + + def test_different_thread(self): + # Lock can be released from a different thread. + lock = self.locktype() + lock.acquire() + def f(): + lock.release() + b = Bunch(f, 1) + b.wait_for_finished() + lock.acquire() + lock.release() + + +class RLockTests(BaseLockTests): + """ + Tests for recursive locks. + """ + def test_reacquire(self): + lock = self.locktype() + lock.acquire() + lock.acquire() + lock.release() + lock.acquire() + lock.release() + lock.release() + + def test_release_unacquired(self): + # Cannot release an unacquired lock + lock = self.locktype() + self.assertRaises(RuntimeError, lock.release) + lock.acquire() + lock.acquire() + lock.release() + lock.acquire() + lock.release() + lock.release() + self.assertRaises(RuntimeError, lock.release) + + def test_different_thread(self): + # Cannot release from a different thread + lock = self.locktype() + def f(): + lock.acquire() + b = Bunch(f, 1, True) + try: + self.assertRaises(RuntimeError, lock.release) + finally: + b.do_finish() + + def test__is_owned(self): + lock = self.locktype() + self.assertFalse(lock._is_owned()) + lock.acquire() + self.assertTrue(lock._is_owned()) + lock.acquire() + self.assertTrue(lock._is_owned()) + result = [] + def f(): + result.append(lock._is_owned()) + Bunch(f, 1).wait_for_finished() + self.assertFalse(result[0]) + lock.release() + self.assertTrue(lock._is_owned()) + lock.release() + self.assertFalse(lock._is_owned()) + + +class EventTests(BaseTestCase): + """ + Tests for Event objects. + """ + + def test_is_set(self): + evt = self.eventtype() + self.assertFalse(evt.is_set()) + evt.set() + self.assertTrue(evt.is_set()) + evt.set() + self.assertTrue(evt.is_set()) + evt.clear() + self.assertFalse(evt.is_set()) + evt.clear() + self.assertFalse(evt.is_set()) + + def _check_notify(self, evt): + # All threads get notified + N = 5 + results1 = [] + results2 = [] + def f(): + results1.append(evt.wait()) + results2.append(evt.wait()) + b = Bunch(f, N) + b.wait_for_started() + _wait() + self.assertEqual(len(results1), 0) + evt.set() + b.wait_for_finished() + self.assertEqual(results1, [True] * N) + self.assertEqual(results2, [True] * N) + + def test_notify(self): + evt = self.eventtype() + self._check_notify(evt) + # Another time, after an explicit clear() + evt.set() + evt.clear() + self._check_notify(evt) + + def test_timeout(self): + evt = self.eventtype() + results1 = [] + results2 = [] + N = 5 + def f(): + results1.append(evt.wait(0.0)) + t1 = time.time() + r = evt.wait(0.2) + t2 = time.time() + results2.append((r, t2 - t1)) + Bunch(f, N).wait_for_finished() + self.assertEqual(results1, [False] * N) + for r, dt in results2: + self.assertFalse(r) + self.assertTrue(dt >= 0.2, dt) + # The event is set + results1 = [] + results2 = [] + evt.set() + Bunch(f, N).wait_for_finished() + self.assertEqual(results1, [True] * N) + for r, dt in results2: + self.assertTrue(r) + + +class ConditionTests(BaseTestCase): + """ + Tests for condition variables. + """ + + def test_acquire(self): + cond = self.condtype() + # Be default we have an RLock: the condition can be acquired multiple + # times. + cond.acquire() + cond.acquire() + cond.release() + cond.release() + lock = threading.Lock() + cond = self.condtype(lock) + cond.acquire() + self.assertFalse(lock.acquire(False)) + cond.release() + self.assertTrue(lock.acquire(False)) + self.assertFalse(cond.acquire(False)) + lock.release() + with cond: + self.assertFalse(lock.acquire(False)) + + def test_unacquired_wait(self): + cond = self.condtype() + self.assertRaises(RuntimeError, cond.wait) + + def test_unacquired_notify(self): + cond = self.condtype() + self.assertRaises(RuntimeError, cond.notify) + + def _check_notify(self, cond): + N = 5 + results1 = [] + results2 = [] + phase_num = 0 + def f(): + cond.acquire() + cond.wait() + cond.release() + results1.append(phase_num) + cond.acquire() + cond.wait() + cond.release() + results2.append(phase_num) + b = Bunch(f, N) + b.wait_for_started() + _wait() + self.assertEqual(results1, []) + # Notify 3 threads at first + cond.acquire() + cond.notify(3) + _wait() + phase_num = 1 + cond.release() + while len(results1) < 3: + _wait() + self.assertEqual(results1, [1] * 3) + self.assertEqual(results2, []) + # Notify 5 threads: they might be in their first or second wait + cond.acquire() + cond.notify(5) + _wait() + phase_num = 2 + cond.release() + while len(results1) + len(results2) < 8: + _wait() + self.assertEqual(results1, [1] * 3 + [2] * 2) + self.assertEqual(results2, [2] * 3) + # Notify all threads: they are all in their second wait + cond.acquire() + cond.notify_all() + _wait() + phase_num = 3 + cond.release() + while len(results2) < 5: + _wait() + self.assertEqual(results1, [1] * 3 + [2] * 2) + self.assertEqual(results2, [2] * 3 + [3] * 2) + b.wait_for_finished() + + def test_notify(self): + cond = self.condtype() + self._check_notify(cond) + # A second time, to check internal state is still ok. + self._check_notify(cond) + + def test_timeout(self): + cond = self.condtype() + results = [] + N = 5 + def f(): + cond.acquire() + t1 = time.time() + cond.wait(0.2) + t2 = time.time() + cond.release() + results.append(t2 - t1) + Bunch(f, N).wait_for_finished() + self.assertEqual(len(results), 5) + for dt in results: + self.assertTrue(dt >= 0.2, dt) + + +class BaseSemaphoreTests(BaseTestCase): + """ + Common tests for {bounded, unbounded} semaphore objects. + """ + + def test_constructor(self): + self.assertRaises(ValueError, self.semtype, value = -1) + self.assertRaises(ValueError, self.semtype, value = -sys.maxint) + + def test_acquire(self): + sem = self.semtype(1) + sem.acquire() + sem.release() + sem = self.semtype(2) + sem.acquire() + sem.acquire() + sem.release() + sem.release() + + def test_acquire_destroy(self): + sem = self.semtype() + sem.acquire() + del sem + + def test_acquire_contended(self): + sem = self.semtype(7) + sem.acquire() + N = 10 + results1 = [] + results2 = [] + phase_num = 0 + def f(): + sem.acquire() + results1.append(phase_num) + sem.acquire() + results2.append(phase_num) + b = Bunch(f, 10) + b.wait_for_started() + while len(results1) + len(results2) < 6: + _wait() + self.assertEqual(results1 + results2, [0] * 6) + phase_num = 1 + for i in range(7): + sem.release() + while len(results1) + len(results2) < 13: + _wait() + self.assertEqual(sorted(results1 + results2), [0] * 6 + [1] * 7) + phase_num = 2 + for i in range(6): + sem.release() + while len(results1) + len(results2) < 19: + _wait() + self.assertEqual(sorted(results1 + results2), [0] * 6 + [1] * 7 + [2] * 6) + # The semaphore is still locked + self.assertFalse(sem.acquire(False)) + # Final release, to let the last thread finish + sem.release() + b.wait_for_finished() + + def test_try_acquire(self): + sem = self.semtype(2) + self.assertTrue(sem.acquire(False)) + self.assertTrue(sem.acquire(False)) + self.assertFalse(sem.acquire(False)) + sem.release() + self.assertTrue(sem.acquire(False)) + + def test_try_acquire_contended(self): + sem = self.semtype(4) + sem.acquire() + results = [] + def f(): + results.append(sem.acquire(False)) + results.append(sem.acquire(False)) + Bunch(f, 5).wait_for_finished() + # There can be a thread switch between acquiring the semaphore and + # appending the result, therefore results will not necessarily be + # ordered. + self.assertEqual(sorted(results), [False] * 7 + [True] * 3 ) + + def test_default_value(self): + # The default initial value is 1. + sem = self.semtype() + sem.acquire() + def f(): + sem.acquire() + sem.release() + b = Bunch(f, 1) + b.wait_for_started() + _wait() + self.assertFalse(b.finished) + sem.release() + b.wait_for_finished() + + def test_with(self): + sem = self.semtype(2) + def _with(err=None): + with sem: + self.assertTrue(sem.acquire(False)) + sem.release() + with sem: + self.assertFalse(sem.acquire(False)) + if err: + raise err + _with() + self.assertTrue(sem.acquire(False)) + sem.release() + self.assertRaises(TypeError, _with, TypeError) + self.assertTrue(sem.acquire(False)) + sem.release() + +class SemaphoreTests(BaseSemaphoreTests): + """ + Tests for unbounded semaphores. + """ + + def test_release_unacquired(self): + # Unbounded releases are allowed and increment the semaphore's value + sem = self.semtype(1) + sem.release() + sem.acquire() + sem.acquire() + sem.release() + + +class BoundedSemaphoreTests(BaseSemaphoreTests): + """ + Tests for bounded semaphores. + """ + + def test_release_unacquired(self): + # Cannot go past the initial value + sem = self.semtype() + self.assertRaises(ValueError, sem.release) + sem.acquire() + sem.release() + self.assertRaises(ValueError, sem.release) Modified: python/trunk/Lib/test/test_thread.py ============================================================================== --- python/trunk/Lib/test/test_thread.py (original) +++ python/trunk/Lib/test/test_thread.py Fri Nov 6 23:34:35 2009 @@ -6,6 +6,7 @@ import time import weakref +from test import lock_tests NUMTASKS = 10 NUMTRIPS = 3 @@ -191,8 +192,12 @@ self.done_mutex.release() +class LockTests(lock_tests.LockTests): + locktype = thread.allocate_lock + + def test_main(): - test_support.run_unittest(ThreadRunningTests, BarrierTest) + test_support.run_unittest(ThreadRunningTests, BarrierTest, LockTests) if __name__ == "__main__": test_main() Modified: python/trunk/Lib/test/test_threading.py ============================================================================== --- python/trunk/Lib/test/test_threading.py (original) +++ python/trunk/Lib/test/test_threading.py Fri Nov 6 23:34:35 2009 @@ -11,6 +11,8 @@ import unittest import weakref +from test import lock_tests + # A trivial mutable counter. class Counter(object): def __init__(self): @@ -482,22 +484,6 @@ thread.start() self.assertRaises(RuntimeError, thread.start) - def test_releasing_unacquired_rlock(self): - rlock = threading.RLock() - self.assertRaises(RuntimeError, rlock.release) - - def test_waiting_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.wait) - - def test_notify_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.notify) - - def test_semaphore_with_negative_value(self): - self.assertRaises(ValueError, threading.Semaphore, value = -1) - self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxint) - def test_joining_current_thread(self): current_thread = threading.current_thread() self.assertRaises(RuntimeError, current_thread.join); @@ -512,8 +498,34 @@ self.assertRaises(RuntimeError, setattr, thread, "daemon", True) +class LockTests(lock_tests.LockTests): + locktype = staticmethod(threading.Lock) + +class RLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading.RLock) + +class EventTests(lock_tests.EventTests): + eventtype = staticmethod(threading.Event) + +class ConditionAsRLockTests(lock_tests.RLockTests): + # An Condition uses an RLock by default and exports its API. + locktype = staticmethod(threading.Condition) + +class ConditionTests(lock_tests.ConditionTests): + condtype = staticmethod(threading.Condition) + +class SemaphoreTests(lock_tests.SemaphoreTests): + semtype = staticmethod(threading.Semaphore) + +class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): + semtype = staticmethod(threading.BoundedSemaphore) + + def test_main(): - test.test_support.run_unittest(ThreadTests, + test.test_support.run_unittest(LockTests, RLockTests, EventTests, + ConditionAsRLockTests, ConditionTests, + SemaphoreTests, BoundedSemaphoreTests, + ThreadTests, ThreadJoinOnShutdown, ThreadingExceptionTests, ) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 6 23:34:35 2009 @@ -1551,6 +1551,9 @@ Tests ----- +- Issue #7270: Add some dedicated unit tests for multi-thread synchronization + primitives such as Lock, RLock, Condition, Event and Semaphore. + - Issue #7222: Make thread "reaping" more reliable so that reference leak-chasing test runs give sensible results. The previous method of reaping threads could return successfully while some Thread objects were From python-checkins at python.org Fri Nov 6 23:41:14 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 06 Nov 2009 22:41:14 -0000 Subject: [Python-checkins] r76138 - in python/branches/py3k: Lib/test/lock_tests.py Lib/test/test_thread.py Lib/test/test_threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 6 23:41:14 2009 New Revision: 76138 Log: Merged revisions 76137 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76137 | antoine.pitrou | 2009-11-06 23:34:35 +0100 (ven., 06 nov. 2009) | 4 lines Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. ........ Added: python/branches/py3k/Lib/test/lock_tests.py - copied, changed from r76137, /python/trunk/Lib/test/lock_tests.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_thread.py python/branches/py3k/Lib/test/test_threading.py python/branches/py3k/Misc/NEWS Copied: python/branches/py3k/Lib/test/lock_tests.py (from r76137, /python/trunk/Lib/test/lock_tests.py) ============================================================================== --- /python/trunk/Lib/test/lock_tests.py (original) +++ python/branches/py3k/Lib/test/lock_tests.py Fri Nov 6 23:41:14 2009 @@ -4,11 +4,11 @@ import sys import time -from thread import start_new_thread, get_ident +from _thread import start_new_thread, get_ident import threading import unittest -from test import test_support as support +from test import support def _wait(): @@ -401,7 +401,7 @@ def test_constructor(self): self.assertRaises(ValueError, self.semtype, value = -1) - self.assertRaises(ValueError, self.semtype, value = -sys.maxint) + self.assertRaises(ValueError, self.semtype, value = -sys.maxsize) def test_acquire(self): sem = self.semtype(1) Modified: python/branches/py3k/Lib/test/test_thread.py ============================================================================== --- python/branches/py3k/Lib/test/test_thread.py (original) +++ python/branches/py3k/Lib/test/test_thread.py Fri Nov 6 23:41:14 2009 @@ -6,6 +6,7 @@ import time import weakref +from test import lock_tests NUMTASKS = 10 NUMTRIPS = 3 @@ -188,8 +189,12 @@ if finished: self.done_mutex.release() +class LockTests(lock_tests.LockTests): + locktype = thread.allocate_lock + + def test_main(): - support.run_unittest(ThreadRunningTests, BarrierTest) + support.run_unittest(ThreadRunningTests, BarrierTest, LockTests) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Fri Nov 6 23:41:14 2009 @@ -12,6 +12,8 @@ import weakref import os +from test import lock_tests + # A trivial mutable counter. class Counter(object): def __init__(self): @@ -487,22 +489,6 @@ thread.start() self.assertRaises(RuntimeError, thread.start) - def test_releasing_unacquired_rlock(self): - rlock = threading.RLock() - self.assertRaises(RuntimeError, rlock.release) - - def test_waiting_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.wait) - - def test_notify_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.notify) - - def test_semaphore_with_negative_value(self): - self.assertRaises(ValueError, threading.Semaphore, value = -1) - self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxsize) - def test_joining_current_thread(self): current_thread = threading.current_thread() self.assertRaises(RuntimeError, current_thread.join); @@ -517,11 +503,37 @@ self.assertRaises(RuntimeError, setattr, thread, "daemon", True) +class LockTests(lock_tests.LockTests): + locktype = staticmethod(threading.Lock) + +class RLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading.RLock) + +class EventTests(lock_tests.EventTests): + eventtype = staticmethod(threading.Event) + +class ConditionAsRLockTests(lock_tests.RLockTests): + # An Condition uses an RLock by default and exports its API. + locktype = staticmethod(threading.Condition) + +class ConditionTests(lock_tests.ConditionTests): + condtype = staticmethod(threading.Condition) + +class SemaphoreTests(lock_tests.SemaphoreTests): + semtype = staticmethod(threading.Semaphore) + +class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): + semtype = staticmethod(threading.BoundedSemaphore) + + def test_main(): - test.support.run_unittest(ThreadTests, - ThreadJoinOnShutdown, - ThreadingExceptionTests, - ) + test.support.run_unittest(LockTests, RLockTests, EventTests, + ConditionAsRLockTests, ConditionTests, + SemaphoreTests, BoundedSemaphoreTests, + ThreadTests, + ThreadJoinOnShutdown, + ThreadingExceptionTests, + ) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Nov 6 23:41:14 2009 @@ -357,6 +357,9 @@ Tests ----- +- Issue #7270: Add some dedicated unit tests for multi-thread synchronization + primitives such as Lock, RLock, Condition, Event and Semaphore. + - Issue #7248 (part 2): Use a unique temporary directory for importlib source tests instead of tempfile.tempdir. This prevents the tests from sharing state between concurrent executions on the same system. From nnorwitz at gmail.com Sat Nov 7 00:01:34 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 6 Nov 2009 18:01:34 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091106230134.GA7695@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_warnings leaked [0, 120, 0] references, sum=120 test_zipimport_support leaked [25, 0, 0] references, sum=25 Less important issues: ---------------------- test_threading leaked [48, 48, 48] references, sum=144 From python-checkins at python.org Sat Nov 7 02:04:39 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 07 Nov 2009 01:04:39 -0000 Subject: [Python-checkins] r76139 - python/trunk/Parser/tokenizer.c Message-ID: Author: benjamin.peterson Date: Sat Nov 7 02:04:38 2009 New Revision: 76139 Log: spelling Modified: python/trunk/Parser/tokenizer.c Modified: python/trunk/Parser/tokenizer.c ============================================================================== --- python/trunk/Parser/tokenizer.c (original) +++ python/trunk/Parser/tokenizer.c Sat Nov 7 02:04:38 2009 @@ -943,7 +943,7 @@ { if (c != EOF) { if (--tok->cur < tok->buf) - Py_FatalError("tok_backup: begin of buffer"); + Py_FatalError("tok_backup: beginning of buffer"); if (*tok->cur != c) *tok->cur = c; } From python-checkins at python.org Sat Nov 7 09:13:55 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 07 Nov 2009 08:13:55 -0000 Subject: [Python-checkins] r76140 - python/trunk/Lib/test/test_runpy.py Message-ID: Author: nick.coghlan Date: Sat Nov 7 09:13:55 2009 New Revision: 76140 Log: Add test for runpy.run_module package execution and use something other than logging as the example of a non-executable package Modified: python/trunk/Lib/test/test_runpy.py Modified: python/trunk/Lib/test/test_runpy.py ============================================================================== --- python/trunk/Lib/test/test_runpy.py (original) +++ python/trunk/Lib/test/test_runpy.py Sat Nov 7 09:13:55 2009 @@ -94,8 +94,8 @@ self.expect_import_error("a.bee") self.expect_import_error(".howard") self.expect_import_error("..eaten") - # Package - self.expect_import_error("logging") + # Package without __main__.py + self.expect_import_error("multiprocessing") def test_library_module(self): run_module("runpy") @@ -107,9 +107,9 @@ pkg_file.close() return pkg_fname - def _make_pkg(self, source, depth): + def _make_pkg(self, source, depth, mod_base="runpy_test"): pkg_name = "__runpy_pkg__" - test_fname = "runpy_test"+os.extsep+"py" + test_fname = mod_base+os.extsep+"py" pkg_dir = sub_dir = tempfile.mkdtemp() if verbose: print " Package tree in:", sub_dir sys.path.insert(0, pkg_dir) @@ -124,7 +124,7 @@ mod_file.write(source) mod_file.close() if verbose: print " Created:", mod_fname - mod_name = (pkg_name+".")*depth + "runpy_test" + mod_name = (pkg_name+".")*depth + mod_base return pkg_dir, mod_fname, mod_name def _del_pkg(self, top, depth, mod_name): @@ -173,6 +173,28 @@ self._del_pkg(pkg_dir, depth, mod_name) if verbose: print "Module executed successfully" + def _check_package(self, depth): + pkg_dir, mod_fname, mod_name = ( + self._make_pkg("x=1\n", depth, "__main__")) + pkg_name, _, _ = mod_name.rpartition(".") + forget(mod_name) + try: + if verbose: print "Running from source:", pkg_name + d1 = run_module(pkg_name) # Read from source + self.assertTrue("x" in d1) + self.assertTrue(d1["x"] == 1) + del d1 # Ensure __loader__ entry doesn't keep file open + __import__(mod_name) + os.remove(mod_fname) + if verbose: print "Running from compiled:", pkg_name + d2 = run_module(pkg_name) # Read from bytecode + self.assertTrue("x" in d2) + self.assertTrue(d2["x"] == 1) + del d2 # Ensure __loader__ entry doesn't keep file open + finally: + self._del_pkg(pkg_dir, depth, pkg_name) + if verbose: print "Package executed successfully" + def _add_relative_modules(self, base_dir, source, depth): if depth <= 1: raise ValueError("Relative module test needs depth > 1") @@ -234,6 +256,11 @@ if verbose: print "Testing package depth:", depth self._check_module(depth) + def test_run_package(self): + for depth in range(1, 4): + if verbose: print "Testing package depth:", depth + self._check_package(depth) + def test_explicit_relative_import(self): for depth in range(2, 5): if verbose: print "Testing relative imports at depth:", depth From python-checkins at python.org Sat Nov 7 09:15:01 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 07 Nov 2009 08:15:01 -0000 Subject: [Python-checkins] r76141 - python/trunk/Lib/runpy.py Message-ID: Author: nick.coghlan Date: Sat Nov 7 09:15:01 2009 New Revision: 76141 Log: Some minor cleanups to private runpy code and docstrings Modified: python/trunk/Lib/runpy.py Modified: python/trunk/Lib/runpy.py ============================================================================== --- python/trunk/Lib/runpy.py (original) +++ python/trunk/Lib/runpy.py Sat Nov 7 09:15:01 2009 @@ -24,7 +24,7 @@ def _run_code(code, run_globals, init_globals=None, mod_name=None, mod_fname=None, mod_loader=None, pkg_name=None): - """Helper for _run_module_code""" + """Helper to run code in nominated namespace""" if init_globals is not None: run_globals.update(init_globals) run_globals.update(__name__ = mod_name, @@ -37,7 +37,7 @@ def _run_module_code(code, init_globals=None, mod_name=None, mod_fname=None, mod_loader=None, pkg_name=None): - """Helper for run_module""" + """Helper to run code in new namespace with sys modified""" # Set up the top level namespace dictionary temp_module = imp.new_module(mod_name) mod_globals = temp_module.__dict__ @@ -81,7 +81,7 @@ raise ImportError("No module named %s" % mod_name) if loader.is_package(mod_name): if mod_name == "__main__" or mod_name.endswith(".__main__"): - raise ImportError(("Cannot use package as __main__ module")) + raise ImportError("Cannot use package as __main__ module") try: pkg_main_name = mod_name + ".__main__" return _get_module_details(pkg_main_name) @@ -99,19 +99,25 @@ # (Current thoughts: don't repeat the mistake that lead to its # creation when run_module() no longer met the needs of # mainmodule.c, but couldn't be changed because it was public) -def _run_module_as_main(mod_name, set_argv0=True): +def _run_module_as_main(mod_name, alter_argv=True): """Runs the designated module in the __main__ namespace - These __*__ magic variables will be overwritten: + Note that the executed module will have full access to the + __main__ namespace. If this is not desirable, the run_module() + function sbould be used to run the module code in a fresh namespace. + + At the very least, these variables in __main__ will be overwritten: + __name__ __file__ __loader__ + __package__ """ try: mod_name, loader, code, fname = _get_module_details(mod_name) except ImportError as exc: # Try to provide a good error message # for directories, zip files and the -m switch - if set_argv0: + if alter_argv: # For -m switch, just display the exception info = str(exc) else: @@ -122,7 +128,7 @@ sys.exit(msg) pkg_name = mod_name.rpartition('.')[0] main_globals = sys.modules["__main__"].__dict__ - if set_argv0: + if alter_argv: sys.argv[0] = fname return _run_code(code, main_globals, None, "__main__", fname, loader, pkg_name) From python-checkins at python.org Sat Nov 7 09:22:58 2009 From: python-checkins at python.org (brett.cannon) Date: Sat, 07 Nov 2009 08:22:58 -0000 Subject: [Python-checkins] r76142 - python/branches/py3k/Doc/library/importlib.rst Message-ID: Author: brett.cannon Date: Sat Nov 7 09:22:58 2009 New Revision: 76142 Log: Pluralize a word. Modified: python/branches/py3k/Doc/library/importlib.rst Modified: python/branches/py3k/Doc/library/importlib.rst ============================================================================== --- python/branches/py3k/Doc/library/importlib.rst (original) +++ python/branches/py3k/Doc/library/importlib.rst Sat Nov 7 09:22:58 2009 @@ -342,7 +342,7 @@ terms of :data:`sys.path`. No implicit path hooks are assumed for simplification of the class and its semantics. - Only class method are defined by this class to alleviate the need for + Only class methods are defined by this class to alleviate the need for instantiation. .. classmethod:: find_module(fullname, path=None) From python-checkins at python.org Sat Nov 7 09:26:08 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 07 Nov 2009 08:26:08 -0000 Subject: [Python-checkins] r76143 - python/trunk/Doc/library/turtle.rst Message-ID: Author: georg.brandl Date: Sat Nov 7 09:26:07 2009 New Revision: 76143 Log: #7271: fix typo. Modified: python/trunk/Doc/library/turtle.rst Modified: python/trunk/Doc/library/turtle.rst ============================================================================== --- python/trunk/Doc/library/turtle.rst (original) +++ python/trunk/Doc/library/turtle.rst Sat Nov 7 09:26:07 2009 @@ -1901,7 +1901,7 @@ Subclass of TurtleScreen, with :ref:`four methods added `. -.. class:: ScrolledCavas(master) +.. class:: ScrolledCanvas(master) :param master: some Tkinter widget to contain the ScrolledCanvas, i.e. a Tkinter-canvas with scrollbars added From python-checkins at python.org Sat Nov 7 19:30:30 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 07 Nov 2009 18:30:30 -0000 Subject: [Python-checkins] r76144 - in sandbox/trunk/newgil: Doc/library/importlib.rst Lib/test/lock_tests.py Lib/test/test_thread.py Lib/test/test_threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sat Nov 7 19:30:30 2009 New Revision: 76144 Log: Merged revisions 76138,76142 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76138 | antoine.pitrou | 2009-11-06 23:41:14 +0100 (ven., 06 nov. 2009) | 10 lines Merged revisions 76137 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76137 | antoine.pitrou | 2009-11-06 23:34:35 +0100 (ven., 06 nov. 2009) | 4 lines Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. ........ ................ r76142 | brett.cannon | 2009-11-07 09:22:58 +0100 (sam., 07 nov. 2009) | 1 line Pluralize a word. ................ Added: sandbox/trunk/newgil/Lib/test/lock_tests.py - copied unchanged from r76142, /python/branches/py3k/Lib/test/lock_tests.py Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Doc/library/importlib.rst sandbox/trunk/newgil/Lib/test/test_thread.py sandbox/trunk/newgil/Lib/test/test_threading.py sandbox/trunk/newgil/Misc/NEWS Modified: sandbox/trunk/newgil/Doc/library/importlib.rst ============================================================================== --- sandbox/trunk/newgil/Doc/library/importlib.rst (original) +++ sandbox/trunk/newgil/Doc/library/importlib.rst Sat Nov 7 19:30:30 2009 @@ -342,7 +342,7 @@ terms of :data:`sys.path`. No implicit path hooks are assumed for simplification of the class and its semantics. - Only class method are defined by this class to alleviate the need for + Only class methods are defined by this class to alleviate the need for instantiation. .. classmethod:: find_module(fullname, path=None) Modified: sandbox/trunk/newgil/Lib/test/test_thread.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_thread.py (original) +++ sandbox/trunk/newgil/Lib/test/test_thread.py Sat Nov 7 19:30:30 2009 @@ -6,6 +6,7 @@ import time import weakref +from test import lock_tests NUMTASKS = 10 NUMTRIPS = 3 @@ -188,8 +189,12 @@ if finished: self.done_mutex.release() +class LockTests(lock_tests.LockTests): + locktype = thread.allocate_lock + + def test_main(): - support.run_unittest(ThreadRunningTests, BarrierTest) + support.run_unittest(ThreadRunningTests, BarrierTest, LockTests) if __name__ == "__main__": test_main() Modified: sandbox/trunk/newgil/Lib/test/test_threading.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_threading.py (original) +++ sandbox/trunk/newgil/Lib/test/test_threading.py Sat Nov 7 19:30:30 2009 @@ -12,6 +12,8 @@ import weakref import os +from test import lock_tests + # A trivial mutable counter. class Counter(object): def __init__(self): @@ -487,22 +489,6 @@ thread.start() self.assertRaises(RuntimeError, thread.start) - def test_releasing_unacquired_rlock(self): - rlock = threading.RLock() - self.assertRaises(RuntimeError, rlock.release) - - def test_waiting_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.wait) - - def test_notify_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.notify) - - def test_semaphore_with_negative_value(self): - self.assertRaises(ValueError, threading.Semaphore, value = -1) - self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxsize) - def test_joining_current_thread(self): current_thread = threading.current_thread() self.assertRaises(RuntimeError, current_thread.join); @@ -517,11 +503,37 @@ self.assertRaises(RuntimeError, setattr, thread, "daemon", True) +class LockTests(lock_tests.LockTests): + locktype = staticmethod(threading.Lock) + +class RLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading.RLock) + +class EventTests(lock_tests.EventTests): + eventtype = staticmethod(threading.Event) + +class ConditionAsRLockTests(lock_tests.RLockTests): + # An Condition uses an RLock by default and exports its API. + locktype = staticmethod(threading.Condition) + +class ConditionTests(lock_tests.ConditionTests): + condtype = staticmethod(threading.Condition) + +class SemaphoreTests(lock_tests.SemaphoreTests): + semtype = staticmethod(threading.Semaphore) + +class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): + semtype = staticmethod(threading.BoundedSemaphore) + + def test_main(): - test.support.run_unittest(ThreadTests, - ThreadJoinOnShutdown, - ThreadingExceptionTests, - ) + test.support.run_unittest(LockTests, RLockTests, EventTests, + ConditionAsRLockTests, ConditionTests, + SemaphoreTests, BoundedSemaphoreTests, + ThreadTests, + ThreadJoinOnShutdown, + ThreadingExceptionTests, + ) if __name__ == "__main__": test_main() Modified: sandbox/trunk/newgil/Misc/NEWS ============================================================================== --- sandbox/trunk/newgil/Misc/NEWS (original) +++ sandbox/trunk/newgil/Misc/NEWS Sat Nov 7 19:30:30 2009 @@ -357,6 +357,9 @@ Tests ----- +- Issue #7270: Add some dedicated unit tests for multi-thread synchronization + primitives such as Lock, RLock, Condition, Event and Semaphore. + - Issue #7248 (part 2): Use a unique temporary directory for importlib source tests instead of tempfile.tempdir. This prevents the tests from sharing state between concurrent executions on the same system. From python-checkins at python.org Sat Nov 7 21:35:04 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 07 Nov 2009 20:35:04 -0000 Subject: [Python-checkins] r76145 - in sandbox/trunk/newgil: Include/ceval.h Modules/_io/fileio.c Modules/_multiprocessing/connection.h Modules/_multiprocessing/pipe_connection.c Modules/_multiprocessing/socket_connection.c Modules/_ssl.c Modules/bz2module.c Modules/posixmodule.c Modules/selectmodule.c Modules/socketmodule.c Python/ceval.c Python/ceval_gil.h Message-ID: Author: antoine.pitrou Date: Sat Nov 7 21:35:04 2009 New Revision: 76145 Log: Remove priority requests altogether. Modified: sandbox/trunk/newgil/Include/ceval.h sandbox/trunk/newgil/Modules/_io/fileio.c sandbox/trunk/newgil/Modules/_multiprocessing/connection.h sandbox/trunk/newgil/Modules/_multiprocessing/pipe_connection.c sandbox/trunk/newgil/Modules/_multiprocessing/socket_connection.c sandbox/trunk/newgil/Modules/_ssl.c sandbox/trunk/newgil/Modules/bz2module.c sandbox/trunk/newgil/Modules/posixmodule.c sandbox/trunk/newgil/Modules/selectmodule.c sandbox/trunk/newgil/Modules/socketmodule.c sandbox/trunk/newgil/Python/ceval.c sandbox/trunk/newgil/Python/ceval_gil.h Modified: sandbox/trunk/newgil/Include/ceval.h ============================================================================== --- sandbox/trunk/newgil/Include/ceval.h (original) +++ sandbox/trunk/newgil/Include/ceval.h Sat Nov 7 21:35:04 2009 @@ -159,7 +159,6 @@ PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); -PyAPI_FUNC(void) PyEval_RestoreThreadPrio(PyThreadState *, int prio); #ifdef WITH_THREAD @@ -181,8 +180,6 @@ #define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ } -#define Py_END_ALLOW_THREADS_PRIO(x) PyEval_RestoreThreadPrio(_save, (x)); \ - } #else /* !WITH_THREAD */ Modified: sandbox/trunk/newgil/Modules/_io/fileio.c ============================================================================== --- sandbox/trunk/newgil/Modules/_io/fileio.c (original) +++ sandbox/trunk/newgil/Modules/_io/fileio.c Sat Nov 7 21:35:04 2009 @@ -476,7 +476,7 @@ Py_BEGIN_ALLOW_THREADS errno = 0; n = read(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS_PRIO(n > 0) + Py_END_ALLOW_THREADS } else n = -1; PyBuffer_Release(&pbuf); @@ -559,7 +559,7 @@ n = read(self->fd, PyBytes_AS_STRING(result) + total, newsize - total); - Py_END_ALLOW_THREADS_PRIO(n > 0) + Py_END_ALLOW_THREADS if (n == 0) break; if (n < 0) { @@ -615,7 +615,7 @@ Py_BEGIN_ALLOW_THREADS errno = 0; n = read(self->fd, ptr, size); - Py_END_ALLOW_THREADS_PRIO(n > 0) + Py_END_ALLOW_THREADS } else n = -1; Modified: sandbox/trunk/newgil/Modules/_multiprocessing/connection.h ============================================================================== --- sandbox/trunk/newgil/Modules/_multiprocessing/connection.h (original) +++ sandbox/trunk/newgil/Modules/_multiprocessing/connection.h Sat Nov 7 21:35:04 2009 @@ -367,7 +367,7 @@ Py_BEGIN_ALLOW_THREADS res = conn_poll(self, timeout, _save); - Py_END_ALLOW_THREADS_PRIO(res == TRUE) + Py_END_ALLOW_THREADS switch (res) { case TRUE: Modified: sandbox/trunk/newgil/Modules/_multiprocessing/pipe_connection.c ============================================================================== --- sandbox/trunk/newgil/Modules/_multiprocessing/pipe_connection.c (original) +++ sandbox/trunk/newgil/Modules/_multiprocessing/pipe_connection.c Sat Nov 7 21:35:04 2009 @@ -49,7 +49,7 @@ Py_BEGIN_ALLOW_THREADS ret = ReadFile(conn->handle, buffer, MIN(buflength, maxlength), &length, NULL); - Py_END_ALLOW_THREADS_PRIO(ret) + Py_END_ALLOW_THREADS if (ret) return length; @@ -75,7 +75,7 @@ Py_BEGIN_ALLOW_THREADS ret = ReadFile(conn->handle, *newbuffer+length, left, &length, NULL); - Py_END_ALLOW_THREADS_PRIO(ret) + Py_END_ALLOW_THREADS if (ret) { assert(length == left); return full_length; Modified: sandbox/trunk/newgil/Modules/_multiprocessing/socket_connection.c ============================================================================== --- sandbox/trunk/newgil/Modules/_multiprocessing/socket_connection.c (original) +++ sandbox/trunk/newgil/Modules/_multiprocessing/socket_connection.c Sat Nov 7 21:35:04 2009 @@ -124,7 +124,7 @@ Py_BEGIN_ALLOW_THREADS res = _conn_recvall(conn->handle, (char*)&ulength, 4); - Py_END_ALLOW_THREADS_PRIO(res == MP_SUCCESS) + Py_END_ALLOW_THREADS if (res < 0) return res; @@ -135,7 +135,7 @@ if (ulength <= buflength) { Py_BEGIN_ALLOW_THREADS res = _conn_recvall(conn->handle, buffer, (size_t)ulength); - Py_END_ALLOW_THREADS_PRIO(res == MP_SUCCESS) + Py_END_ALLOW_THREADS return res < 0 ? res : ulength; } else { *newbuffer = PyMem_Malloc((size_t)ulength); @@ -143,7 +143,7 @@ return MP_MEMORY_ERROR; Py_BEGIN_ALLOW_THREADS res = _conn_recvall(conn->handle, *newbuffer, (size_t)ulength); - Py_END_ALLOW_THREADS_PRIO(res == MP_SUCCESS) + Py_END_ALLOW_THREADS return res < 0 ? (Py_ssize_t)res : (Py_ssize_t)ulength; } } Modified: sandbox/trunk/newgil/Modules/_ssl.c ============================================================================== --- sandbox/trunk/newgil/Modules/_ssl.c (original) +++ sandbox/trunk/newgil/Modules/_ssl.c Sat Nov 7 21:35:04 2009 @@ -24,9 +24,6 @@ #define PySSL_UNBLOCK_THREADS if (_ssl_locks_count>0){_save = PyEval_SaveThread()}; #define PySSL_END_ALLOW_THREADS if (_ssl_locks_count>0){PyEval_RestoreThread(_save);} \ } -#define PySSL_END_ALLOW_THREADS_PRIO(x) \ - if (_ssl_locks_count>0){PyEval_RestoreThreadPrio(_save, (x));} \ - } #else /* no WITH_THREAD */ @@ -34,7 +31,6 @@ #define PySSL_BLOCK_THREADS #define PySSL_UNBLOCK_THREADS #define PySSL_END_ALLOW_THREADS -#define PySSL_END_ALLOW_THREADS_PRIO(x) #endif @@ -1114,7 +1110,7 @@ timeout = (int)(s->sock_timeout * 1000 + 0.5); PySSL_BEGIN_ALLOW_THREADS rc = poll(&pollfd, 1, timeout); - PySSL_END_ALLOW_THREADS_PRIO(rc > 0) + PySSL_END_ALLOW_THREADS goto normal_return; } @@ -1138,7 +1134,7 @@ rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv); else rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv); - PySSL_END_ALLOW_THREADS_PRIO(rc > 0) + PySSL_END_ALLOW_THREADS #ifdef HAVE_POLL normal_return: @@ -1298,7 +1294,7 @@ /* first check if there are bytes ready to be read */ PySSL_BEGIN_ALLOW_THREADS count = SSL_pending(self->ssl); - PySSL_END_ALLOW_THREADS_PRIO(count > 0) + PySSL_END_ALLOW_THREADS if (!count) { sockstate = check_socket_and_wait_for_timeout(sock, 0); @@ -1320,7 +1316,7 @@ PySSL_BEGIN_ALLOW_THREADS count = SSL_read(self->ssl, mem, len); err = SSL_get_error(self->ssl, count); - PySSL_END_ALLOW_THREADS_PRIO(count > 0) + PySSL_END_ALLOW_THREADS if (PyErr_CheckSignals()) goto error; if (err == SSL_ERROR_WANT_READ) { Modified: sandbox/trunk/newgil/Modules/bz2module.c ============================================================================== --- sandbox/trunk/newgil/Modules/bz2module.c (original) +++ sandbox/trunk/newgil/Modules/bz2module.c Sat Nov 7 21:35:04 2009 @@ -253,8 +253,7 @@ break; *buf++ = c; } while (bzerror == BZ_OK && c != '\n' && buf != end); - Py_END_ALLOW_THREADS_PRIO(bzerror == BZ_STREAM_END || - bzerror == BZ_OK) + Py_END_ALLOW_THREADS if (bzerror == BZ_STREAM_END) { f->size = f->pos; f->mode = MODE_READ_EOF; @@ -328,8 +327,7 @@ } Py_BEGIN_ALLOW_THREADS chunksize = BZ2_bzRead(&bzerror, f->fp, f->f_buf, bufsize); - Py_END_ALLOW_THREADS_PRIO(bzerror == BZ_STREAM_END || - bzerror == BZ_OK) + Py_END_ALLOW_THREADS f->pos += chunksize; if (bzerror == BZ_STREAM_END) { f->size = f->pos; @@ -450,8 +448,7 @@ BUF(ret)+bytesread, buffersize-bytesread); self->pos += chunksize; - Py_END_ALLOW_THREADS_PRIO(bzerror == BZ_STREAM_END || - bzerror == BZ_OK) + Py_END_ALLOW_THREADS bytesread += chunksize; if (bzerror == BZ_STREAM_END) { self->size = self->pos; @@ -584,8 +581,7 @@ nread = BZ2_bzRead(&bzerror, self->fp, buffer+nfilled, buffersize-nfilled); self->pos += nread; - Py_END_ALLOW_THREADS_PRIO(bzerror == BZ_STREAM_END || - bzerror == BZ_OK) + Py_END_ALLOW_THREADS if (bzerror == BZ_STREAM_END) { self->size = self->pos; self->mode = MODE_READ_EOF; @@ -942,9 +938,7 @@ chunksize = BZ2_bzRead(&bzerror, self->fp, buffer, buffersize); self->pos += chunksize; - Py_END_ALLOW_THREADS_PRIO( - bzerror == BZ_STREAM_END || - bzerror == BZ_OK) + Py_END_ALLOW_THREADS bytesread += chunksize; if (bzerror == BZ_STREAM_END) { @@ -1003,8 +997,7 @@ Py_BEGIN_ALLOW_THREADS chunksize = BZ2_bzRead(&bzerror, self->fp, buffer, readsize); self->pos += chunksize; - Py_END_ALLOW_THREADS_PRIO(bzerror == BZ_STREAM_END || - bzerror == BZ_OK) + Py_END_ALLOW_THREADS bytesread += chunksize; if (bzerror == BZ_STREAM_END) { self->size = self->pos; Modified: sandbox/trunk/newgil/Modules/posixmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/posixmodule.c (original) +++ sandbox/trunk/newgil/Modules/posixmodule.c Sat Nov 7 21:35:04 2009 @@ -2197,7 +2197,7 @@ } Py_BEGIN_ALLOW_THREADS result = FindNextFileW(hFindFile, &wFileData); - Py_END_ALLOW_THREADS_PRIO(result) + Py_END_ALLOW_THREADS /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ if (!result && GetLastError() != ERROR_NO_MORE_FILES) { @@ -2270,7 +2270,7 @@ } Py_BEGIN_ALLOW_THREADS result = FindNextFile(hFindFile, &FileData); - Py_END_ALLOW_THREADS_PRIO(result) + Py_END_ALLOW_THREADS /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ if (!result && GetLastError() != ERROR_NO_MORE_FILES) { @@ -2395,7 +2395,7 @@ errno = 0; Py_BEGIN_ALLOW_THREADS ep = readdir(dirp); - Py_END_ALLOW_THREADS_PRIO(ep || !errno) + Py_END_ALLOW_THREADS if (ep == NULL) { if (errno == 0) { break; @@ -4461,7 +4461,7 @@ Py_BEGIN_ALLOW_THREADS pid = wait3(&status, options, &ru); - Py_END_ALLOW_THREADS_PRIO(pid > 0) + Py_END_ALLOW_THREADS return wait_helper(pid, WAIT_STATUS_INT(status), &ru); } @@ -4486,7 +4486,7 @@ Py_BEGIN_ALLOW_THREADS pid = wait4(pid, &status, options, &ru); - Py_END_ALLOW_THREADS_PRIO(pid > 0) + Py_END_ALLOW_THREADS return wait_helper(pid, WAIT_STATUS_INT(status), &ru); } @@ -4509,7 +4509,7 @@ return NULL; Py_BEGIN_ALLOW_THREADS pid = waitpid(pid, &status, options); - Py_END_ALLOW_THREADS_PRIO(pid > 0) + Py_END_ALLOW_THREADS if (pid == -1) return posix_error(); @@ -4533,7 +4533,7 @@ return NULL; Py_BEGIN_ALLOW_THREADS pid = _cwait(&status, pid, options); - Py_END_ALLOW_THREADS_PRIO(pid > 0) + Py_END_ALLOW_THREADS if (pid == -1) return posix_error(); @@ -4556,7 +4556,7 @@ Py_BEGIN_ALLOW_THREADS pid = wait(&status); - Py_END_ALLOW_THREADS_PRIO(pid > 0) + Py_END_ALLOW_THREADS if (pid == -1) return posix_error(); @@ -5037,7 +5037,7 @@ return posix_error(); Py_BEGIN_ALLOW_THREADS n = read(fd, PyBytes_AS_STRING(buffer), size); - Py_END_ALLOW_THREADS_PRIO(n > 0) + Py_END_ALLOW_THREADS if (n < 0) { Py_DECREF(buffer); return posix_error(); Modified: sandbox/trunk/newgil/Modules/selectmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/selectmodule.c (original) +++ sandbox/trunk/newgil/Modules/selectmodule.c Sat Nov 7 21:35:04 2009 @@ -273,7 +273,7 @@ Py_BEGIN_ALLOW_THREADS n = select(max, &ifdset, &ofdset, &efdset, tvp); - Py_END_ALLOW_THREADS_PRIO(n > 0) + Py_END_ALLOW_THREADS #ifdef MS_WINDOWS if (n == SOCKET_ERROR) { @@ -532,7 +532,7 @@ /* call poll() */ Py_BEGIN_ALLOW_THREADS poll_result = poll(self->ufds, self->ufd_len, timeout); - Py_END_ALLOW_THREADS_PRIO(poll_result > 0) + Py_END_ALLOW_THREADS if (poll_result < 0) { PyErr_SetFromErrno(SelectError); @@ -1023,7 +1023,7 @@ Py_BEGIN_ALLOW_THREADS nfds = epoll_wait(self->epfd, evs, maxevents, timeout); - Py_END_ALLOW_THREADS_PRIO(nfds > 0) + Py_END_ALLOW_THREADS if (nfds < 0) { PyErr_SetFromErrno(PyExc_IOError); goto error; @@ -1608,7 +1608,7 @@ Py_BEGIN_ALLOW_THREADS gotevents = kevent(self->kqfd, chl, nchanges, evl, nevents, ptimeoutspec); - Py_END_ALLOW_THREADS_PRIO(gotevents > 0) + Py_END_ALLOW_THREADS if (gotevents == -1) { PyErr_SetFromErrno(PyExc_OSError); Modified: sandbox/trunk/newgil/Modules/socketmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/socketmodule.c (original) +++ sandbox/trunk/newgil/Modules/socketmodule.c Sat Nov 7 21:35:04 2009 @@ -1591,7 +1591,7 @@ timeout = internal_select(s, 0); if (!timeout) newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); - Py_END_ALLOW_THREADS_PRIO(!timeout) + Py_END_ALLOW_THREADS if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); @@ -1967,7 +1967,7 @@ Py_BEGIN_ALLOW_THREADS res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); - Py_END_ALLOW_THREADS_PRIO(res == 0) + Py_END_ALLOW_THREADS if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); @@ -2001,7 +2001,7 @@ Py_BEGIN_ALLOW_THREADS res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); - Py_END_ALLOW_THREADS_PRIO(res == 0) + Py_END_ALLOW_THREADS /* Signals are not errors (though they may raise exceptions). Adapted from PyErr_SetFromErrnoWithFilenameObject(). */ @@ -2155,7 +2155,7 @@ timeout = internal_select(s, 0); if (!timeout) outlen = recv(s->sock_fd, cbuf, len, flags); - Py_END_ALLOW_THREADS_PRIO(outlen > 0) + Py_END_ALLOW_THREADS if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); @@ -2186,7 +2186,7 @@ timeout = internal_select(s, 0); if (!timeout) nread = recv(s->sock_fd, read_buf, segment, flags); - Py_END_ALLOW_THREADS_PRIO(nread > 0) + Py_END_ALLOW_THREADS if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); @@ -2370,7 +2370,7 @@ SAS2SA(&addrbuf), &addrlen); #endif } - Py_END_ALLOW_THREADS_PRIO(n > 0) + Py_END_ALLOW_THREADS if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); Modified: sandbox/trunk/newgil/Python/ceval.c ============================================================================== --- sandbox/trunk/newgil/Python/ceval.c (original) +++ sandbox/trunk/newgil/Python/ceval.c Sat Nov 7 21:35:04 2009 @@ -392,29 +392,20 @@ } void -PyEval_RestoreThreadPrio(PyThreadState *tstate, int prio) +PyEval_RestoreThread(PyThreadState *tstate) { if (tstate == NULL) Py_FatalError("PyEval_RestoreThread: NULL tstate"); #ifdef WITH_THREAD if (gil_created()) { int err = errno; - if (prio) - take_gil_prio(tstate); - else - take_gil(tstate); + take_gil(tstate); errno = err; } #endif PyThreadState_Swap(tstate); } -void -PyEval_RestoreThread(PyThreadState *tstate) -{ - PyEval_RestoreThreadPrio(tstate, 0); -} - /* Mechanism whereby asynchronously executing callbacks (e.g. UNIX signal handlers or Mac I/O completion routines) can schedule calls Modified: sandbox/trunk/newgil/Python/ceval_gil.h ============================================================================== --- sandbox/trunk/newgil/Python/ceval_gil.h (original) +++ sandbox/trunk/newgil/Python/ceval_gil.h Sat Nov 7 21:35:04 2009 @@ -17,13 +17,6 @@ #undef FORCE_SWITCHING #define FORCE_SWITCHING -/* Enable priority requests */ -#undef PRIO_REQUESTS -/* #define PRIO_REQUESTS */ - -#undef TRACE_PRIO -/* #define TRACE_PRIO */ - /* Notes about the implementation: @@ -53,10 +46,6 @@ by waiting on a variable (gil_last_holder) controlled through another {mutex, condition} pair. - - An optional policy mechanism, priority requests, is currently disabled. - The intent was to further improve the latency of some types of GIL-taking - activities, such as being woken up on a socket. If it is confirmed that - this feature is unnecessary, support code should be removed. */ #ifndef _POSIX_THREADS @@ -217,21 +206,6 @@ static MUTEX_T switch_mutex; #endif -/* This mutex is taken when a priority request is made, and released when - it is finally honoured. - Other threads can sleep by trying to lock the mutex. */ -static MUTEX_T prio_mutex; -/* The thread making the prio request, or NULL. */ -static volatile PyThreadState *prio_request = NULL; - -#define YIELD_IF_PRIO_REQUEST() \ -do { \ - if (prio_request) { \ - MUTEX_LOCK(prio_mutex); \ - MUTEX_UNLOCK(prio_mutex); \ - } \ -} while (0) - static int gil_created(void) { @@ -241,9 +215,6 @@ static void create_gil(void) { MUTEX_INIT(gil_mutex); -#ifdef PRIO_REQUESTS - MUTEX_INIT(prio_mutex); -#endif #ifdef FORCE_SWITCHING MUTEX_INIT(switch_mutex); #endif @@ -253,7 +224,6 @@ #endif gil_locked = 0; gil_last_holder = NULL; - prio_request = NULL; } static void recreate_gil(void) @@ -288,59 +258,23 @@ #endif } -static void _take_gil(PyThreadState *tstate, int prio) +static void take_gil(PyThreadState *tstate) { int err; if (tstate == NULL) Py_FatalError("take_gil: NULL tstate"); - /* If another thread is requesting priority, give it a chance to run - before we take the mutex. - */ -#ifdef PRIO_REQUESTS - YIELD_IF_PRIO_REQUEST(); -#endif - err = errno; MUTEX_LOCK(gil_mutex); - if (!gil_locked) { - prio = 0; + if (!gil_locked) goto _ready; - } COND_PREPARE(gil_cond); - - if (prio) { -#ifdef TRACE_PRIO - struct timeval tv; - GETTIMEOFDAY(&tv); - printf("trying to take gil with prio: %.3f <--\n", - tv.tv_sec + tv.tv_usec / 1000000.0); -#endif - if (!prio_request) { - MUTEX_LOCK(prio_mutex); - prio_request = tstate; - } - else - prio = 0; - } while (gil_locked) { int timed_out = 0; unsigned long saved_switchnum; - if (prio_request) { - /* Tell the eval loop the GIL must be dropped as soon as possible */ - SET_GIL_DROP_REQUEST(); - if (!prio) { - /* If another thread is making the prio_request, give it a - chance to run and take the mutex. */ - MUTEX_UNLOCK(gil_mutex); - YIELD_IF_PRIO_REQUEST(); - MUTEX_LOCK(gil_mutex); - } - } - saved_switchnum = gil_switch_number; COND_TIMED_WAIT(gil_cond, gil_mutex, INTERVAL, timed_out); /* If we timed out and no switch occurred in the meantime, it is time @@ -360,26 +294,12 @@ if (tstate != gil_last_holder) { gil_last_holder = tstate; ++gil_switch_number; -#ifdef TRACE_PRIO - if (prio) { - struct timeval tv; - GETTIMEOFDAY(&tv); - printf("gil taken with prio: %.3f\n", - tv.tv_sec + tv.tv_usec / 1000000.0); - } -#endif } #ifdef FORCE_SWITCHING COND_SIGNAL(switch_cond); MUTEX_UNLOCK(switch_mutex); #endif - if (prio) { - /* The prio request was granted. */ - prio_request = NULL; - MUTEX_UNLOCK(prio_mutex); - } - if (gil_drop_request && !prio_request) { - /* No prio_request pending. */ + if (gil_drop_request) { RESET_GIL_DROP_REQUEST(); } if (tstate->async_exc != NULL) { @@ -390,20 +310,6 @@ errno = err; } -static void take_gil(PyThreadState *tstate) -{ - _take_gil(tstate, 0); -} - -static void take_gil_prio(PyThreadState *tstate) -{ -#ifdef PRIO_REQUESTS - _take_gil(tstate, 1); -#else - _take_gil(tstate, 0); -#endif -} - void _PyEval_SetSwitchInterval(unsigned long microseconds) { gil_interval = microseconds; From nnorwitz at gmail.com Sat Nov 7 23:51:06 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 7 Nov 2009 17:51:06 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091107225106.GA26354@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [420, -420, 420] references, sum=420 Less important issues: ---------------------- test_threading leaked [1728, 1728, 1728] references, sum=5184 From python-checkins at python.org Sun Nov 8 00:55:06 2009 From: python-checkins at python.org (brett.cannon) Date: Sat, 07 Nov 2009 23:55:06 -0000 Subject: [Python-checkins] r76146 - in python/branches/py3k: Lib/importlib/_bootstrap.py Lib/importlib/test/source/test_file_loader.py Misc/ACKS Misc/NEWS Message-ID: Author: brett.cannon Date: Sun Nov 8 00:55:05 2009 New Revision: 76146 Log: When trying to write new bytecode, importlib was not catching the IOError thrown if the file happened to be read-only to keep the failure silent. Fixes issue #7187. Thanks, Dave Malcolm for the report and analysis of the problem. Modified: python/branches/py3k/Lib/importlib/_bootstrap.py python/branches/py3k/Lib/importlib/test/source/test_file_loader.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/importlib/_bootstrap.py ============================================================================== --- python/branches/py3k/Lib/importlib/_bootstrap.py (original) +++ python/branches/py3k/Lib/importlib/_bootstrap.py Sun Nov 8 00:55:05 2009 @@ -526,9 +526,9 @@ bytecode_path = self.bytecode_path(name) if not bytecode_path: bytecode_path = self._base_path + _suffix_list(imp.PY_COMPILED)[0] - file = _io.FileIO(bytecode_path, 'w') # Assuming bytes. try: - with _closing(file) as bytecode_file: + # Assuming bytes. + with _closing(_io.FileIO(bytecode_path, 'w')) as bytecode_file: bytecode_file.write(data) return True except IOError as exc: Modified: python/branches/py3k/Lib/importlib/test/source/test_file_loader.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/source/test_file_loader.py (original) +++ python/branches/py3k/Lib/importlib/test/source/test_file_loader.py Sun Nov 8 00:55:05 2009 @@ -6,6 +6,7 @@ import imp import os import py_compile +import stat import sys import unittest @@ -121,6 +122,10 @@ But if the marshal data is bad, even if the magic number and timestamp work, a ValueError is raised and the source is not used [bad marshal]. + The case of not being able to write out the bytecode must also be handled + as it's possible it was made read-only. In that instance the attempt to + write the bytecode should fail silently [bytecode read-only]. + """ def import_(self, file, module_name): @@ -159,6 +164,7 @@ self.assertEqual(bytecode_file.read(4), source_timestamp) # [bad marshal] + @source_util.writes_bytecode_files def test_bad_marshal(self): with source_util.create_modules('_temp') as mapping: bytecode_path = source_util.bytecode_path(mapping['_temp']) @@ -172,6 +178,26 @@ self.import_(mapping['_temp'], '_temp') self.assertTrue('_temp' not in sys.modules) + # [bytecode read-only] + @source_util.writes_bytecode_files + def test_read_only_bytecode(self): + with source_util.create_modules('_temp') as mapping: + # Create bytecode that will need to be re-created. + py_compile.compile(mapping['_temp']) + bytecode_path = source_util.bytecode_path(mapping['_temp']) + with open(bytecode_path, 'r+b') as bytecode_file: + bytecode_file.seek(0) + bytecode_file.write(b'\x00\x00\x00\x00') + # Make the bytecode read-only. + os.chmod(bytecode_path, + stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + try: + # Should not raise IOError! + self.import_(mapping['_temp'], '_temp') + finally: + # Make writable for eventual clean-up. + os.chmod(bytecode_path, stat.S_IWUSR) + def test_main(): from test.support import run_unittest Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sun Nov 8 00:55:05 2009 @@ -472,6 +472,7 @@ Don MacMillen Steve Majewski Grzegorz Makarewicz +Dave Malcolm Ken Manheimer Vladimir Marangozov David Marek Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 8 00:55:05 2009 @@ -123,6 +123,9 @@ Library ------- +- Issue #7187: Importlib would not silence the IOError raised when trying to + write new bytecode when it was made read-only. + - Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. From python-checkins at python.org Sun Nov 8 00:57:21 2009 From: python-checkins at python.org (brett.cannon) Date: Sat, 07 Nov 2009 23:57:21 -0000 Subject: [Python-checkins] r76147 - in python/branches/release31-maint: Lib/importlib/_bootstrap.py Lib/importlib/test/source/test_file_loader.py Misc/ACKS Misc/NEWS Message-ID: Author: brett.cannon Date: Sun Nov 8 00:57:20 2009 New Revision: 76147 Log: Merged revisions 76146 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76146 | brett.cannon | 2009-11-07 15:55:05 -0800 (Sat, 07 Nov 2009) | 6 lines When trying to write new bytecode, importlib was not catching the IOError thrown if the file happened to be read-only to keep the failure silent. Fixes issue #7187. Thanks, Dave Malcolm for the report and analysis of the problem. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/importlib/_bootstrap.py python/branches/release31-maint/Lib/importlib/test/source/test_file_loader.py python/branches/release31-maint/Misc/ACKS python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/importlib/_bootstrap.py ============================================================================== --- python/branches/release31-maint/Lib/importlib/_bootstrap.py (original) +++ python/branches/release31-maint/Lib/importlib/_bootstrap.py Sun Nov 8 00:57:20 2009 @@ -522,9 +522,9 @@ bytecode_path = self.bytecode_path(name) if not bytecode_path: bytecode_path = self._base_path + _suffix_list(imp.PY_COMPILED)[0] - file = _io.FileIO(bytecode_path, 'w') # Assuming bytes. try: - with _closing(file) as bytecode_file: + # Assuming bytes. + with _closing(_io.FileIO(bytecode_path, 'w')) as bytecode_file: bytecode_file.write(data) return True except IOError as exc: Modified: python/branches/release31-maint/Lib/importlib/test/source/test_file_loader.py ============================================================================== --- python/branches/release31-maint/Lib/importlib/test/source/test_file_loader.py (original) +++ python/branches/release31-maint/Lib/importlib/test/source/test_file_loader.py Sun Nov 8 00:57:20 2009 @@ -6,6 +6,7 @@ import imp import os import py_compile +import stat import sys import unittest @@ -119,6 +120,10 @@ But if the marshal data is bad, even if the magic number and timestamp work, a ValueError is raised and the source is not used [bad marshal]. + The case of not being able to write out the bytecode must also be handled + as it's possible it was made read-only. In that instance the attempt to + write the bytecode should fail silently [bytecode read-only]. + """ def import_(self, file, module_name): @@ -157,6 +162,7 @@ self.assertEqual(bytecode_file.read(4), source_timestamp) # [bad marshal] + @source_util.writes_bytecode_files def test_bad_marshal(self): with source_util.create_modules('_temp') as mapping: bytecode_path = source_util.bytecode_path(mapping['_temp']) @@ -170,6 +176,26 @@ '_temp') self.assertTrue('_temp' not in sys.modules) + # [bytecode read-only] + @source_util.writes_bytecode_files + def test_read_only_bytecode(self): + with source_util.create_modules('_temp') as mapping: + # Create bytecode that will need to be re-created. + py_compile.compile(mapping['_temp']) + bytecode_path = source_util.bytecode_path(mapping['_temp']) + with open(bytecode_path, 'r+b') as bytecode_file: + bytecode_file.seek(0) + bytecode_file.write(b'\x00\x00\x00\x00') + # Make the bytecode read-only. + os.chmod(bytecode_path, + stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + try: + # Should not raise IOError! + self.import_(mapping['_temp'], '_temp') + finally: + # Make writable for eventual clean-up. + os.chmod(bytecode_path, stat.S_IWUSR) + def test_main(): from test.support import run_unittest Modified: python/branches/release31-maint/Misc/ACKS ============================================================================== --- python/branches/release31-maint/Misc/ACKS (original) +++ python/branches/release31-maint/Misc/ACKS Sun Nov 8 00:57:20 2009 @@ -466,6 +466,7 @@ Don MacMillen Steve Majewski Grzegorz Makarewicz +Dave Malcolm Ken Manheimer Vladimir Marangozov David Marek Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Nov 8 00:57:20 2009 @@ -40,6 +40,9 @@ Library ------- +- Issue #7187: Importlib would not silence the IOError raised when trying to + write new bytecode when it was made read-only. + - Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. From solipsis at pitrou.net Sun Nov 8 01:03:51 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Sun, 8 Nov 2009 00:03:51 +0000 (UTC) Subject: [Python-checkins] Python Regression Test Failures refleak (1) References: <20091107225106.GA26354@kbk-i386-bb.psfb.org> Message-ID: Neal Norwitz gmail.com> writes: > > Less important issues: > ---------------------- > test_threading leaked [1728, 1728, 1728] references, sum=5184 Impressive! A couple of those leaks is due to http://bugs.python.org/issue7282 (coupled with the new tests), but I'm surprised you get so many of them. You should probably investigate things a bit. cheers Antoine. From python-checkins at python.org Sun Nov 8 01:24:12 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 08 Nov 2009 00:24:12 -0000 Subject: [Python-checkins] r76148 - python/trunk/Lib/test/test_threading.py Message-ID: Author: antoine.pitrou Date: Sun Nov 8 01:24:12 2009 New Revision: 76148 Log: Kill a small potential leak in test_threading. The leak may not manifest itself if the OS re-uses the same thread ids (I suppose Neal's machine doesn't :-)) Modified: python/trunk/Lib/test/test_threading.py Modified: python/trunk/Lib/test/test_threading.py ============================================================================== --- python/trunk/Lib/test/test_threading.py (original) +++ python/trunk/Lib/test/test_threading.py Sun Nov 8 01:24:12 2009 @@ -111,6 +111,8 @@ thread.start_new_thread(f, ()) done.wait() self.assertFalse(ident[0] is None) + # Kill the "immortal" _DummyThread + del threading._active[ident[0]] # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): From python-checkins at python.org Sun Nov 8 01:30:05 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 08 Nov 2009 00:30:05 -0000 Subject: [Python-checkins] r76149 - in python/branches/py3k: Lib/test/test_threading.py Message-ID: Author: antoine.pitrou Date: Sun Nov 8 01:30:04 2009 New Revision: 76149 Log: Merged revisions 76148 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76148 | antoine.pitrou | 2009-11-08 01:24:12 +0100 (dim., 08 nov. 2009) | 4 lines Kill a small potential leak in test_threading. The leak may not manifest itself if the OS re-uses the same thread ids (I suppose Neal's machine doesn't :-)) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_threading.py Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Sun Nov 8 01:30:04 2009 @@ -113,6 +113,8 @@ _thread.start_new_thread(f, ()) done.wait() self.assertFalse(ident[0] is None) + # Kill the "immortal" _DummyThread + del threading._active[ident[0]] # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): From python-checkins at python.org Sun Nov 8 01:36:34 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 08 Nov 2009 00:36:34 -0000 Subject: [Python-checkins] r76150 - in python/branches/release26-maint: Lib/test/test_threading.py Message-ID: Author: antoine.pitrou Date: Sun Nov 8 01:36:33 2009 New Revision: 76150 Log: Merged revisions 76148 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76148 | antoine.pitrou | 2009-11-08 01:24:12 +0100 (dim., 08 nov. 2009) | 4 lines Kill a small potential leak in test_threading. The leak may not manifest itself if the OS re-uses the same thread ids (I suppose Neal's machine doesn't :-)) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_threading.py Modified: python/branches/release26-maint/Lib/test/test_threading.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_threading.py (original) +++ python/branches/release26-maint/Lib/test/test_threading.py Sun Nov 8 01:36:33 2009 @@ -100,6 +100,8 @@ thread.start_new_thread(f, ()) done.wait() self.assertFalse(ident[0] is None) + # Kill the "immortal" _DummyThread + del threading._active[ident[0]] # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): From python-checkins at python.org Sun Nov 8 01:36:37 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 08 Nov 2009 00:36:37 -0000 Subject: [Python-checkins] r76151 - in python/branches/release31-maint: Lib/test/test_threading.py Message-ID: Author: antoine.pitrou Date: Sun Nov 8 01:36:36 2009 New Revision: 76151 Log: Merged revisions 76149 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76149 | antoine.pitrou | 2009-11-08 01:30:04 +0100 (dim., 08 nov. 2009) | 11 lines Merged revisions 76148 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76148 | antoine.pitrou | 2009-11-08 01:24:12 +0100 (dim., 08 nov. 2009) | 4 lines Kill a small potential leak in test_threading. The leak may not manifest itself if the OS re-uses the same thread ids (I suppose Neal's machine doesn't :-)) ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_threading.py Modified: python/branches/release31-maint/Lib/test/test_threading.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_threading.py (original) +++ python/branches/release31-maint/Lib/test/test_threading.py Sun Nov 8 01:36:36 2009 @@ -101,6 +101,8 @@ _thread.start_new_thread(f, ()) done.wait() self.assertFalse(ident[0] is None) + # Kill the "immortal" _DummyThread + del threading._active[ident[0]] # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): From nnorwitz at gmail.com Sun Nov 8 11:51:56 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 8 Nov 2009 05:51:56 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091108105156.GA14805@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [420, -420, 420] references, sum=420 Less important issues: ---------------------- test_threading leaked [1680, 1680, 1680] references, sum=5040 From python-checkins at python.org Sun Nov 8 17:31:01 2009 From: python-checkins at python.org (andrew.kuchling) Date: Sun, 08 Nov 2009 16:31:01 -0000 Subject: [Python-checkins] r76152 - peps/trunk/pep-0372.txt Message-ID: Author: andrew.kuchling Date: Sun Nov 8 17:31:00 2009 New Revision: 76152 Log: Grammar fix Modified: peps/trunk/pep-0372.txt Modified: peps/trunk/pep-0372.txt ============================================================================== --- peps/trunk/pep-0372.txt (original) +++ peps/trunk/pep-0372.txt Sun Nov 8 17:31:00 2009 @@ -196,7 +196,7 @@ In Py2.6, the object_hook for json decoders passes-in an already built dictionary so order is lost before the object hook sees it. This - problem is being fixed for Python 2.7/3.1 by adding an new hook that + problem is being fixed for Python 2.7/3.1 by adding a new hook that preserves order (see http://bugs.python.org/issue5381 ). With the new hook, order can be preserved:: From python-checkins at python.org Sun Nov 8 17:31:29 2009 From: python-checkins at python.org (andrew.kuchling) Date: Sun, 08 Nov 2009 16:31:29 -0000 Subject: [Python-checkins] r76153 - peps/trunk/pep-3003.txt Message-ID: Author: andrew.kuchling Date: Sun Nov 8 17:31:29 2009 New Revision: 76153 Log: Grammar, wording fixes Modified: peps/trunk/pep-3003.txt Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Sun Nov 8 17:31:29 2009 @@ -41,13 +41,13 @@ Python 3.x was a large part of the last several years of Python's development. Its release, as well as a bevy of changes to the language -introduce by it and the previous 2.6.x releases, puts alternative +introduced by it and the previous 2.6.x releases, puts alternative implementations at a severe disadvantage in "keeping pace" with core python development. Additionally, many of the changes put into the recent releases of the language -as implemented by CPython have not yet seen widespread usage amongst the -general user population. For example, most users are beholden to the version +as implemented by CPython have not yet seen widespread usage by the +general user population. For example, most users are limited to the version of the interpreter (typically CPython) which comes pre-installed with their operating system. Most OS vendors are just barely beginning to ship Python 2.6 -- even fewer are shipping Python 3.x. @@ -116,7 +116,7 @@ * The standard library As the standard library is not directly tied to the language definition it is not covered by this moratorium. -* Backports of 3.x features to to 2.x +* Backports of 3.x features to 2.x The moratorium only affects features that would be new in 3.x. * Import semantics For example, PEP 382. After all, import semantics vary between From python-checkins at python.org Sun Nov 8 22:35:28 2009 From: python-checkins at python.org (brett.cannon) Date: Sun, 08 Nov 2009 21:35:28 -0000 Subject: [Python-checkins] r76154 - in python/trunk/Misc: NEWS Vim/vimrc Message-ID: Author: brett.cannon Date: Sun Nov 8 22:35:28 2009 New Revision: 76154 Log: Properly detect whether a C file is using tabs or spaces for Vim. Closes issue #5611. Thanks Kirk McDonald and Johannes Hoff. Modified: python/trunk/Misc/NEWS python/trunk/Misc/Vim/vimrc Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 8 22:35:28 2009 @@ -1607,6 +1607,11 @@ - Issue #2389: Array objects are now pickled in a portable manner. +Misc +---- + +- Issue #5611: Auto-detect whether a C file uses tabs or spaces in Vim. + What's New in Python 2.6 final ============================== Modified: python/trunk/Misc/Vim/vimrc ============================================================================== --- python/trunk/Misc/Vim/vimrc (original) +++ python/trunk/Misc/Vim/vimrc Sun Nov 8 22:35:28 2009 @@ -15,31 +15,29 @@ " Only basic settings needed to enforce the style guidelines are set. " Some suggested options are listed but commented out at the end of this file. - -" Number of spaces to use for an indent. -" This will affect Ctrl-T and 'autoindent'. -" Python: 4 spaces -" C: 8 spaces (pre-existing files) or 4 spaces (new files) -au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 -au BufRead *.c,*.h set shiftwidth=8 -au BufNewFile *.c,*.h set shiftwidth=4 - " Number of spaces that a pre-existing tab is equal to. " For the amount of space used for a new tab use shiftwidth. -" Python: 8 -" C: 8 au BufRead,BufNewFile *py,*pyw,*.c,*.h set tabstop=8 -" Replace tabs with the equivalent number of spaces. -" Also have an autocmd for Makefiles since they require hard tabs. -" Python: yes -" C: no -" Makefile: no +" What to use for an indent. +" This will affect Ctrl-T and 'autoindent'. +" Python: 4 spaces +" C: tabs (pre-existing files) or 4 spaces (new files) +au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 au BufRead,BufNewFile *.py,*.pyw set expandtab -au BufRead,BufNewFile *.c,*.h set noexpandtab +fu Select_c_style() + if search('^\t', 'n', 150) + set shiftwidth=8 + set noexpandtab + el + set shiftwidth=4 + set expandtab + en +endf +au BufRead,BufNewFile *.c,*.h call Select_c_style() au BufRead,BufNewFile Makefile* set noexpandtab -" Use the below highlight group when displaying bad whitespace is desired +" Use the below highlight group when displaying bad whitespace is desired. highlight BadWhitespace ctermbg=red guibg=red " Display tabs at the beginning of a line in Python mode as bad. From python-checkins at python.org Sun Nov 8 22:41:28 2009 From: python-checkins at python.org (brett.cannon) Date: Sun, 08 Nov 2009 21:41:28 -0000 Subject: [Python-checkins] r76155 - in python/branches/py3k: Misc/Vim/vimrc Message-ID: Author: brett.cannon Date: Sun Nov 8 22:41:27 2009 New Revision: 76155 Log: Blocked revisions 76154 via svnmerge ........ r76154 | brett.cannon | 2009-11-08 13:35:28 -0800 (Sun, 08 Nov 2009) | 4 lines Properly detect whether a C file is using tabs or spaces for Vim. Closes issue #5611. Thanks Kirk McDonald and Johannes Hoff. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/Vim/vimrc Modified: python/branches/py3k/Misc/Vim/vimrc ============================================================================== --- python/branches/py3k/Misc/Vim/vimrc (original) +++ python/branches/py3k/Misc/Vim/vimrc Sun Nov 8 22:41:27 2009 @@ -15,35 +15,32 @@ " Only basic settings needed to enforce the style guidelines are set. " Some suggested options are listed but commented out at the end of this file. - -" Number of spaces to use for an indent. -" This will affect Ctrl-T and 'autoindent'. -" Python: 4 spaces -" C: 4 spaces -au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 -au BufRead *.c,*.h set shiftwidth=8 -au BufNewFile *.c,*.h set shiftwidth=4 - " Number of spaces that a pre-existing tab is equal to. " For the amount of space used for a new tab use shiftwidth. -" Python: 8 -" C: 8 au BufRead,BufNewFile *py,*pyw,*.c,*.h set tabstop=8 -" Replace tabs with the equivalent number of spaces. -" Also have an autocmd for Makefiles since they require hard tabs. -" Python: yes -" C: yes -" Makefile: no -au BufRead,BufNewFile *.py,*.pyw,*.c,*.h set expandtab +" What to use for an indent. +" This will affect Ctrl-T and 'autoindent'. +" Python: 4 spaces +" C: tabs (pre-existing files) or 4 spaces (new files) +au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 +au BufRead,BufNewFile *.py,*.pyw set expandtab +fu Select_c_style() + if search('^\t', 'n', 150) + set shiftwidth=8 + set noexpandtab + el + set shiftwidth=4 + set expandtab + en +endf +au BufRead,BufNewFile *.c,*.h call Select_c_style() au BufRead,BufNewFile Makefile* set noexpandtab -" Use the below highlight group when displaying bad whitespace is desired +" Use the below highlight group when displaying bad whitespace is desired. highlight BadWhitespace ctermbg=red guibg=red " Display tabs at the beginning of a line in Python mode as bad. -" Should be done for C code, but not until all code has been moved to 4-space -" indents. au BufRead,BufNewFile *.py,*.pyw match BadWhitespace /^\t\+/ " Make trailing whitespace be flagged as bad. au BufRead,BufNewFile *.py,*.pyw,*.c,*.h match BadWhitespace /\s\+$/ From python-checkins at python.org Mon Nov 9 01:42:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 00:42:59 -0000 Subject: [Python-checkins] r76156 - in python/branches/py3k/Tools/scripts: db2pickle.py pickle2db.py redemo.py Message-ID: Author: benjamin.peterson Date: Mon Nov 9 01:42:58 2009 New Revision: 76156 Log: fix some imports Modified: python/branches/py3k/Tools/scripts/db2pickle.py python/branches/py3k/Tools/scripts/pickle2db.py python/branches/py3k/Tools/scripts/redemo.py Modified: python/branches/py3k/Tools/scripts/db2pickle.py ============================================================================== --- python/branches/py3k/Tools/scripts/db2pickle.py (original) +++ python/branches/py3k/Tools/scripts/db2pickle.py Mon Nov 9 01:42:58 2009 @@ -33,12 +33,12 @@ except ImportError: gdbm = None try: - import dbm as anydbm + import dbm.ndbm as anydbm except ImportError: anydbm = None import sys try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle Modified: python/branches/py3k/Tools/scripts/pickle2db.py ============================================================================== --- python/branches/py3k/Tools/scripts/pickle2db.py (original) +++ python/branches/py3k/Tools/scripts/pickle2db.py Mon Nov 9 01:42:58 2009 @@ -38,12 +38,12 @@ except ImportError: gdbm = None try: - import dbm as anydbm + import dbm.ndbm as anydbm except ImportError: anydbm = None import sys try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle Modified: python/branches/py3k/Tools/scripts/redemo.py ============================================================================== --- python/branches/py3k/Tools/scripts/redemo.py (original) +++ python/branches/py3k/Tools/scripts/redemo.py Mon Nov 9 01:42:58 2009 @@ -1,6 +1,6 @@ """Basic regular expression demostration facility (Perl style syntax).""" -from Tkinter import * +from tkinter import * import re class ReDemo: From python-checkins at python.org Mon Nov 9 01:45:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 00:45:40 -0000 Subject: [Python-checkins] r76157 - in python/branches/release31-maint: Tools/scripts/db2pickle.py Tools/scripts/pickle2db.py Tools/scripts/redemo.py Message-ID: Author: benjamin.peterson Date: Mon Nov 9 01:45:40 2009 New Revision: 76157 Log: Merged revisions 76156 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76156 | benjamin.peterson | 2009-11-08 18:42:58 -0600 (Sun, 08 Nov 2009) | 1 line fix some imports ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Tools/scripts/db2pickle.py python/branches/release31-maint/Tools/scripts/pickle2db.py python/branches/release31-maint/Tools/scripts/redemo.py Modified: python/branches/release31-maint/Tools/scripts/db2pickle.py ============================================================================== --- python/branches/release31-maint/Tools/scripts/db2pickle.py (original) +++ python/branches/release31-maint/Tools/scripts/db2pickle.py Mon Nov 9 01:45:40 2009 @@ -33,12 +33,12 @@ except ImportError: gdbm = None try: - import dbm as anydbm + import dbm.ndbm as anydbm except ImportError: anydbm = None import sys try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle Modified: python/branches/release31-maint/Tools/scripts/pickle2db.py ============================================================================== --- python/branches/release31-maint/Tools/scripts/pickle2db.py (original) +++ python/branches/release31-maint/Tools/scripts/pickle2db.py Mon Nov 9 01:45:40 2009 @@ -38,12 +38,12 @@ except ImportError: gdbm = None try: - import dbm as anydbm + import dbm.ndbm as anydbm except ImportError: anydbm = None import sys try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle Modified: python/branches/release31-maint/Tools/scripts/redemo.py ============================================================================== --- python/branches/release31-maint/Tools/scripts/redemo.py (original) +++ python/branches/release31-maint/Tools/scripts/redemo.py Mon Nov 9 01:45:40 2009 @@ -1,6 +1,6 @@ """Basic regular expression demostration facility (Perl style syntax).""" -from Tkinter import * +from tkinter import * import re class ReDemo: From python-checkins at python.org Mon Nov 9 01:49:19 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 00:49:19 -0000 Subject: [Python-checkins] r76158 - python/branches/py3k/Tools/scripts/win_add2path.py Message-ID: Author: benjamin.peterson Date: Mon Nov 9 01:49:19 2009 New Revision: 76158 Log: convert to use print() function Modified: python/branches/py3k/Tools/scripts/win_add2path.py Modified: python/branches/py3k/Tools/scripts/win_add2path.py ============================================================================== --- python/branches/py3k/Tools/scripts/win_add2path.py (original) +++ python/branches/py3k/Tools/scripts/win_add2path.py Mon Nov 9 01:49:19 2009 @@ -45,13 +45,13 @@ def main(): paths, envpath = modify() if len(paths) > 1: - print "Path(s) added:" - print '\n'.join(paths[1:]) + print("Path(s) added:") + print('\n'.join(paths[1:])) else: - print "No path was added" - print "\nPATH is now:\n%s\n" % envpath - print "Expanded:" - print winreg.ExpandEnvironmentStrings(envpath) + print("No path was added") + print("\nPATH is now:\n%s\n" % envpath) + print("Expanded:") + print(winreg.ExpandEnvironmentStrings(envpath)) if __name__ == '__main__': main() From python-checkins at python.org Mon Nov 9 01:52:04 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 00:52:04 -0000 Subject: [Python-checkins] r76159 - in python/branches/release31-maint: Tools/scripts/win_add2path.py Message-ID: Author: benjamin.peterson Date: Mon Nov 9 01:52:04 2009 New Revision: 76159 Log: Merged revisions 76158 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76158 | benjamin.peterson | 2009-11-08 18:49:19 -0600 (Sun, 08 Nov 2009) | 1 line convert to use print() function ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Tools/scripts/win_add2path.py Modified: python/branches/release31-maint/Tools/scripts/win_add2path.py ============================================================================== --- python/branches/release31-maint/Tools/scripts/win_add2path.py (original) +++ python/branches/release31-maint/Tools/scripts/win_add2path.py Mon Nov 9 01:52:04 2009 @@ -45,13 +45,13 @@ def main(): paths, envpath = modify() if len(paths) > 1: - print "Path(s) added:" - print '\n'.join(paths[1:]) + print("Path(s) added:") + print('\n'.join(paths[1:])) else: - print "No path was added" - print "\nPATH is now:\n%s\n" % envpath - print "Expanded:" - print winreg.ExpandEnvironmentStrings(envpath) + print("No path was added") + print("\nPATH is now:\n%s\n" % envpath) + print("Expanded:") + print(winreg.ExpandEnvironmentStrings(envpath)) if __name__ == '__main__': main() From python-checkins at python.org Mon Nov 9 01:53:48 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 00:53:48 -0000 Subject: [Python-checkins] r76160 - in sandbox/trunk/2to3/lib2to3: main.py refactor.py tests/test_refactor.py Message-ID: Author: benjamin.peterson Date: Mon Nov 9 01:53:48 2009 New Revision: 76160 Log: undeprecate the -p option; it's useful for converting python3 sources Modified: sandbox/trunk/2to3/lib2to3/main.py sandbox/trunk/2to3/lib2to3/refactor.py sandbox/trunk/2to3/lib2to3/tests/test_refactor.py Modified: sandbox/trunk/2to3/lib2to3/main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/main.py (original) +++ sandbox/trunk/2to3/lib2to3/main.py Mon Nov 9 01:53:48 2009 @@ -91,8 +91,7 @@ parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") parser.add_option("-p", "--print-function", action="store_true", - help="DEPRECATED Modify the grammar so that print() is " - "a function") + help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", @@ -104,12 +103,10 @@ # Parse command line arguments refactor_stdin = False + flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") - if options.print_function: - warn("-p is deprecated; " - "detection of from __future__ import print_function is automatic") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: @@ -127,6 +124,8 @@ if options.write: print >> sys.stderr, "Can't write to stdin." return 2 + if options.print_function: + flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO @@ -147,7 +146,7 @@ else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) - rt = StdoutRefactoringTool(sorted(fixer_names), None, sorted(explicit), + rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments Modified: sandbox/trunk/2to3/lib2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/refactor.py Mon Nov 9 01:53:48 2009 @@ -18,7 +18,6 @@ import operator import collections import StringIO -import warnings from itertools import chain # Local imports @@ -172,7 +171,7 @@ class RefactoringTool(object): - _default_options = {} + _default_options = {"print_function" : False} CLASS_PREFIX = "Fix" # The prefix for fixer classes FILE_PREFIX = "fix_" # The prefix for modules with a fixer within @@ -189,15 +188,16 @@ self.explicit = explicit or [] self.options = self._default_options.copy() if options is not None: - if "print_function" in options: - warnings.warn("the 'print_function' option is deprecated", - DeprecationWarning) self.options.update(options) + if self.options["print_function"]: + self.grammar = pygram.python_grammar_no_print_statement + else: + self.grammar = pygram.python_grammar self.errors = [] self.logger = logging.getLogger("RefactoringTool") self.fixer_log = [] self.wrote = False - self.driver = driver.Driver(pygram.python_grammar, + self.driver = driver.Driver(self.grammar, convert=pytree.convert, logger=self.logger) self.pre_order, self.post_order = self.get_fixers() @@ -353,7 +353,7 @@ name, err.__class__.__name__, err) return finally: - self.driver.grammar = pygram.python_grammar + self.driver.grammar = self.grammar self.log_debug("Refactoring %s", name) self.refactor_tree(tree, name) return tree Modified: sandbox/trunk/2to3/lib2to3/tests/test_refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_refactor.py Mon Nov 9 01:53:48 2009 @@ -45,12 +45,10 @@ return refactor.RefactoringTool(fixers, options, explicit) def test_print_function_option(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - refactor.RefactoringTool(_DEFAULT_FIXERS, {"print_function" : True}) - self.assertEqual(len(w), 1) - msg, = w - self.assertTrue(msg.category is DeprecationWarning) + rt = self.rt({"print_function" : True}) + self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement) + self.assertTrue(rt.driver.grammar is + pygram.python_grammar_no_print_statement) def test_fixer_loading_helpers(self): contents = ["explicit", "first", "last", "parrot", "preorder"] From python-checkins at python.org Mon Nov 9 02:05:37 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 01:05:37 -0000 Subject: [Python-checkins] r76161 - sandbox/trunk/2to3/lib2to3/refactor.py Message-ID: Author: benjamin.peterson Date: Mon Nov 9 02:05:37 2009 New Revision: 76161 Log: simplify condition Modified: sandbox/trunk/2to3/lib2to3/refactor.py Modified: sandbox/trunk/2to3/lib2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/refactor.py Mon Nov 9 02:05:37 2009 @@ -138,26 +138,23 @@ if have_docstring: break have_docstring = True - elif tp == token.NAME: - if value == u"from": + elif tp == token.NAME and value == u"from": + tp, value = advance() + if tp != token.NAME and value != u"__future__": + break + tp, value = advance() + if tp != token.NAME and value != u"import": + break + tp, value = advance() + if tp == token.OP and value == u"(": tp, value = advance() - if tp != token.NAME and value != u"__future__": - break + while tp == token.NAME: + if value == u"print_function": + return True tp, value = advance() - if tp != token.NAME and value != u"import": + if tp != token.OP and value != u",": break tp, value = advance() - if tp == token.OP and value == u"(": - tp, value = advance() - while tp == token.NAME: - if value == u"print_function": - return True - tp, value = advance() - if tp != token.OP and value != u",": - break - tp, value = advance() - else: - break else: break except StopIteration: From python-checkins at python.org Mon Nov 9 05:10:53 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 09 Nov 2009 04:10:53 -0000 Subject: [Python-checkins] r76162 - python/trunk/Doc/library/2to3.rst Message-ID: Author: benjamin.peterson Date: Mon Nov 9 05:10:53 2009 New Revision: 76162 Log: discuss how to use -p Modified: python/trunk/Doc/library/2to3.rst Modified: python/trunk/Doc/library/2to3.rst ============================================================================== --- python/trunk/Doc/library/2to3.rst (original) +++ python/trunk/Doc/library/2to3.rst Mon Nov 9 05:10:53 2009 @@ -86,6 +86,14 @@ The :option:`-v` option enables output of more information on the translation process. +Since some print statements can be parsed as function calls or statements, 2to3 +cannot always read files containing the print function. When 2to3 detects the +presence of the ``from __future__ import print_function`` compiler directive, it +modifies its internal grammar to interpert :func:`print` as a function. This +change can also be enabled manually with the :option:`-p` flag. Use +:option:`-p` to run fixers on code that already has had its print statements +converted. + .. _2to3-fixers: From nnorwitz at gmail.com Mon Nov 9 11:52:04 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 9 Nov 2009 05:52:04 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091109105204.GA15248@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 91, -22] references, sum=69 Less important issues: ---------------------- test_threading leaked [1680, 1680, 1680] references, sum=5040 From python-checkins at python.org Mon Nov 9 15:18:14 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 09 Nov 2009 14:18:14 -0000 Subject: [Python-checkins] r76163 - python/trunk/Doc/library/csv.rst Message-ID: Author: r.david.murray Date: Mon Nov 9 15:18:14 2009 New Revision: 76163 Log: Remove redundant sentence. Modified: python/trunk/Doc/library/csv.rst Modified: python/trunk/Doc/library/csv.rst ============================================================================== --- python/trunk/Doc/library/csv.rst (original) +++ python/trunk/Doc/library/csv.rst Mon Nov 9 15:18:14 2009 @@ -167,13 +167,12 @@ Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has fewer fields than - the fieldnames sequence, the value of *restval* will be used as the default - value. If the row read has more fields than the fieldnames sequence, the - remaining data is added as a sequence keyed by the value of *restkey*. If the - row read has fewer fields than the fieldnames sequence, the remaining keys take - the value of the optional *restval* parameter. Any other optional or keyword - arguments are passed to the underlying :class:`reader` instance. + *csvfile* will be used as the fieldnames. If the row read has more fields + than the fieldnames sequence, the remaining data is added as a sequence + keyed by the value of *restkey*. If the row read has fewer fields than the + fieldnames sequence, the remaining keys take the value of the optional + *restval* parameter. Any other optional or keyword arguments are passed to + the underlying :class:`reader` instance. .. class:: DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]]) From python-checkins at python.org Mon Nov 9 15:20:12 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 09 Nov 2009 14:20:12 -0000 Subject: [Python-checkins] r76164 - in python/branches/release26-maint: Doc/library/csv.rst Message-ID: Author: r.david.murray Date: Mon Nov 9 15:20:12 2009 New Revision: 76164 Log: Merged revisions 76163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76163 | r.david.murray | 2009-11-09 09:18:14 -0500 (Mon, 09 Nov 2009) | 2 lines Remove redundant sentence. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/csv.rst Modified: python/branches/release26-maint/Doc/library/csv.rst ============================================================================== --- python/branches/release26-maint/Doc/library/csv.rst (original) +++ python/branches/release26-maint/Doc/library/csv.rst Mon Nov 9 15:20:12 2009 @@ -167,13 +167,12 @@ Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has fewer fields than - the fieldnames sequence, the value of *restval* will be used as the default - value. If the row read has more fields than the fieldnames sequence, the - remaining data is added as a sequence keyed by the value of *restkey*. If the - row read has fewer fields than the fieldnames sequence, the remaining keys take - the value of the optional *restval* parameter. Any other optional or keyword - arguments are passed to the underlying :class:`reader` instance. + *csvfile* will be used as the fieldnames. If the row read has more fields + than the fieldnames sequence, the remaining data is added as a sequence + keyed by the value of *restkey*. If the row read has fewer fields than the + fieldnames sequence, the remaining keys take the value of the optional + *restval* parameter. Any other optional or keyword arguments are passed to + the underlying :class:`reader` instance. .. class:: DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]]) From python-checkins at python.org Mon Nov 9 15:21:38 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 09 Nov 2009 14:21:38 -0000 Subject: [Python-checkins] r76165 - in python/branches/py3k: Doc/library/csv.rst Message-ID: Author: r.david.murray Date: Mon Nov 9 15:21:38 2009 New Revision: 76165 Log: Merged revisions 76163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76163 | r.david.murray | 2009-11-09 09:18:14 -0500 (Mon, 09 Nov 2009) | 2 lines Remove redundant sentence. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/csv.rst Modified: python/branches/py3k/Doc/library/csv.rst ============================================================================== --- python/branches/py3k/Doc/library/csv.rst (original) +++ python/branches/py3k/Doc/library/csv.rst Mon Nov 9 15:21:38 2009 @@ -141,13 +141,12 @@ Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has fewer fields than - the fieldnames sequence, the value of *restval* will be used as the default - value. If the row read has more fields than the fieldnames sequence, the - remaining data is added as a sequence keyed by the value of *restkey*. If the - row read has fewer fields than the fieldnames sequence, the remaining keys take - the value of the optional *restval* parameter. Any other optional or keyword - arguments are passed to the underlying :class:`reader` instance. + *csvfile* will be used as the fieldnames. If the row read has more fields + than the fieldnames sequence, the remaining data is added as a sequence + keyed by the value of *restkey*. If the row read has fewer fields than the + fieldnames sequence, the remaining keys take the value of the optional + *restval* parameter. Any other optional or keyword arguments are passed to + the underlying :class:`reader` instance. .. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) From python-checkins at python.org Mon Nov 9 15:22:37 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 09 Nov 2009 14:22:37 -0000 Subject: [Python-checkins] r76166 - in python/branches/release31-maint: Doc/library/csv.rst Message-ID: Author: r.david.murray Date: Mon Nov 9 15:22:36 2009 New Revision: 76166 Log: Merged revisions 76165 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76165 | r.david.murray | 2009-11-09 09:21:38 -0500 (Mon, 09 Nov 2009) | 9 lines Merged revisions 76163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76163 | r.david.murray | 2009-11-09 09:18:14 -0500 (Mon, 09 Nov 2009) | 2 lines Remove redundant sentence. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/csv.rst Modified: python/branches/release31-maint/Doc/library/csv.rst ============================================================================== --- python/branches/release31-maint/Doc/library/csv.rst (original) +++ python/branches/release31-maint/Doc/library/csv.rst Mon Nov 9 15:22:36 2009 @@ -141,13 +141,12 @@ Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has fewer fields than - the fieldnames sequence, the value of *restval* will be used as the default - value. If the row read has more fields than the fieldnames sequence, the - remaining data is added as a sequence keyed by the value of *restkey*. If the - row read has fewer fields than the fieldnames sequence, the remaining keys take - the value of the optional *restval* parameter. Any other optional or keyword - arguments are passed to the underlying :class:`reader` instance. + *csvfile* will be used as the fieldnames. If the row read has more fields + than the fieldnames sequence, the remaining data is added as a sequence + keyed by the value of *restkey*. If the row read has fewer fields than the + fieldnames sequence, the remaining keys take the value of the optional + *restval* parameter. Any other optional or keyword arguments are passed to + the underlying :class:`reader` instance. .. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) From python-checkins at python.org Mon Nov 9 16:16:23 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 09 Nov 2009 15:16:23 -0000 Subject: [Python-checkins] r76168 - python/trunk/Lib/subprocess.py Message-ID: Author: eric.smith Date: Mon Nov 9 16:16:23 2009 New Revision: 76168 Log: Issue 7294: Fixed URL in a comment. Modified: python/trunk/Lib/subprocess.py Modified: python/trunk/Lib/subprocess.py ============================================================================== --- python/trunk/Lib/subprocess.py (original) +++ python/trunk/Lib/subprocess.py Mon Nov 9 16:16:23 2009 @@ -564,7 +564,9 @@ """ # See - # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp + # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + # or search http://msdn.microsoft.com for + # "Parsing C++ Command-Line Arguments" result = [] needquote = False for arg in seq: From python-checkins at python.org Mon Nov 9 16:20:16 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 09 Nov 2009 15:20:16 -0000 Subject: [Python-checkins] r76169 - in python/branches/release26-maint: Lib/subprocess.py Message-ID: Author: eric.smith Date: Mon Nov 9 16:20:16 2009 New Revision: 76169 Log: Merged revisions 76168 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76168 | eric.smith | 2009-11-09 10:16:23 -0500 (Mon, 09 Nov 2009) | 1 line Issue 7294: Fixed URL in a comment. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/subprocess.py Modified: python/branches/release26-maint/Lib/subprocess.py ============================================================================== --- python/branches/release26-maint/Lib/subprocess.py (original) +++ python/branches/release26-maint/Lib/subprocess.py Mon Nov 9 16:20:16 2009 @@ -516,7 +516,9 @@ """ # See - # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp + # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + # or search http://msdn.microsoft.com for + # "Parsing C++ Command-Line Arguments" result = [] needquote = False for arg in seq: From python-checkins at python.org Mon Nov 9 16:23:16 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 09 Nov 2009 15:23:16 -0000 Subject: [Python-checkins] r76170 - in python/branches/py3k: Lib/subprocess.py Message-ID: Author: eric.smith Date: Mon Nov 9 16:23:15 2009 New Revision: 76170 Log: Merged revisions 76168 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76168 | eric.smith | 2009-11-09 10:16:23 -0500 (Mon, 09 Nov 2009) | 1 line Issue 7294: Fixed URL in a comment. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/subprocess.py Modified: python/branches/py3k/Lib/subprocess.py ============================================================================== --- python/branches/py3k/Lib/subprocess.py (original) +++ python/branches/py3k/Lib/subprocess.py Mon Nov 9 16:23:15 2009 @@ -497,7 +497,9 @@ """ # See - # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp + # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + # or search http://msdn.microsoft.com for + # "Parsing C++ Command-Line Arguments" result = [] needquote = False for arg in seq: From python-checkins at python.org Mon Nov 9 16:24:55 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 09 Nov 2009 15:24:55 -0000 Subject: [Python-checkins] r76171 - in python/branches/release31-maint: Lib/subprocess.py Message-ID: Author: eric.smith Date: Mon Nov 9 16:24:55 2009 New Revision: 76171 Log: Merged revisions 76170 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76170 | eric.smith | 2009-11-09 10:23:15 -0500 (Mon, 09 Nov 2009) | 9 lines Merged revisions 76168 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76168 | eric.smith | 2009-11-09 10:16:23 -0500 (Mon, 09 Nov 2009) | 1 line Issue 7294: Fixed URL in a comment. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/subprocess.py Modified: python/branches/release31-maint/Lib/subprocess.py ============================================================================== --- python/branches/release31-maint/Lib/subprocess.py (original) +++ python/branches/release31-maint/Lib/subprocess.py Mon Nov 9 16:24:55 2009 @@ -497,7 +497,9 @@ """ # See - # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp + # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + # or search http://msdn.microsoft.com for + # "Parsing C++ Command-Line Arguments" result = [] needquote = False for arg in seq: From python-checkins at python.org Mon Nov 9 17:00:11 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 09 Nov 2009 16:00:11 -0000 Subject: [Python-checkins] r76172 - in python/trunk: Lib/test/lock_tests.py Lib/test/test_threading.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 9 17:00:11 2009 New Revision: 76172 Log: Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. Modified: python/trunk/Lib/test/lock_tests.py python/trunk/Lib/test/test_threading.py python/trunk/Lib/threading.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/lock_tests.py ============================================================================== --- python/trunk/Lib/test/lock_tests.py (original) +++ python/trunk/Lib/test/lock_tests.py Mon Nov 9 17:00:11 2009 @@ -130,6 +130,19 @@ # Check the lock is unacquired Bunch(f, 1).wait_for_finished() + def test_thread_leak(self): + # The lock shouldn't leak a Thread instance when used from a foreign + # (non-threading) thread. + lock = self.locktype() + def f(): + lock.acquire() + lock.release() + n = len(threading.enumerate()) + # We run many threads in the hope that existing threads ids won't + # be recycled. + Bunch(f, 15).wait_for_finished() + self.assertEqual(n, len(threading.enumerate())) + class LockTests(BaseLockTests): """ Modified: python/trunk/Lib/test/test_threading.py ============================================================================== --- python/trunk/Lib/test/test_threading.py (original) +++ python/trunk/Lib/test/test_threading.py Mon Nov 9 17:00:11 2009 @@ -143,11 +143,9 @@ def test_foreign_thread(self): # Check that a "foreign" thread can use the threading module. def f(mutex): - # Acquiring an RLock forces an entry for the foreign + # Calling current_thread() forces an entry for the foreign # thread to get made in the threading._active map. - r = threading.RLock() - r.acquire() - r.release() + threading.current_thread() mutex.release() mutex = threading.Lock() Modified: python/trunk/Lib/threading.py ============================================================================== --- python/trunk/Lib/threading.py (original) +++ python/trunk/Lib/threading.py Mon Nov 9 17:00:11 2009 @@ -106,14 +106,16 @@ def __repr__(self): owner = self.__owner - return "<%s(%s, %d)>" % ( - self.__class__.__name__, - owner and owner.name, - self.__count) + try: + owner = _active[owner].name + except KeyError: + pass + return "<%s owner=%r count=%d>" % ( + self.__class__.__name__, owner, self.__count) def acquire(self, blocking=1): - me = current_thread() - if self.__owner is me: + me = _get_ident() + if self.__owner == me: self.__count = self.__count + 1 if __debug__: self._note("%s.acquire(%s): recursive success", self, blocking) @@ -132,7 +134,7 @@ __enter__ = acquire def release(self): - if self.__owner is not current_thread(): + if self.__owner != _get_ident(): raise RuntimeError("cannot release un-acquired lock") self.__count = count = self.__count - 1 if not count: @@ -168,7 +170,7 @@ return (count, owner) def _is_owned(self): - return self.__owner is current_thread() + return self.__owner == _get_ident() def Condition(*args, **kwargs): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Nov 9 17:00:11 2009 @@ -426,6 +426,10 @@ Library ------- +- Issue #7282: Fix a memory leak when an RLock was used in a thread other + than those started through `threading.Thread` (for example, using + `thread.start_new_thread()`. + - Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. From python-checkins at python.org Mon Nov 9 17:08:16 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 09 Nov 2009 16:08:16 -0000 Subject: [Python-checkins] r76173 - in python/branches/py3k: Lib/test/lock_tests.py Lib/test/test_threading.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 9 17:08:16 2009 New Revision: 76173 Log: Merged revisions 76172 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76172 | antoine.pitrou | 2009-11-09 17:00:11 +0100 (lun., 09 nov. 2009) | 5 lines Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/lock_tests.py python/branches/py3k/Lib/test/test_threading.py python/branches/py3k/Lib/threading.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/lock_tests.py ============================================================================== --- python/branches/py3k/Lib/test/lock_tests.py (original) +++ python/branches/py3k/Lib/test/lock_tests.py Mon Nov 9 17:08:16 2009 @@ -130,6 +130,19 @@ # Check the lock is unacquired Bunch(f, 1).wait_for_finished() + def test_thread_leak(self): + # The lock shouldn't leak a Thread instance when used from a foreign + # (non-threading) thread. + lock = self.locktype() + def f(): + lock.acquire() + lock.release() + n = len(threading.enumerate()) + # We run many threads in the hope that existing threads ids won't + # be recycled. + Bunch(f, 15).wait_for_finished() + self.assertEqual(n, len(threading.enumerate())) + class LockTests(BaseLockTests): """ Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Mon Nov 9 17:08:16 2009 @@ -143,11 +143,9 @@ def test_foreign_thread(self): # Check that a "foreign" thread can use the threading module. def f(mutex): - # Acquiring an RLock forces an entry for the foreign + # Calling current_thread() forces an entry for the foreign # thread to get made in the threading._active map. - r = threading.RLock() - r.acquire() - r.release() + threading.current_thread() mutex.release() mutex = threading.Lock() Modified: python/branches/py3k/Lib/threading.py ============================================================================== --- python/branches/py3k/Lib/threading.py (original) +++ python/branches/py3k/Lib/threading.py Mon Nov 9 17:08:16 2009 @@ -92,14 +92,16 @@ def __repr__(self): owner = self._owner - return "<%s(%s, %d)>" % ( - self.__class__.__name__, - owner and owner.name, - self._count) + try: + owner = _active[owner].name + except KeyError: + pass + return "<%s owner=%r count=%d>" % ( + self.__class__.__name__, owner, self._count) def acquire(self, blocking=True): - me = current_thread() - if self._owner is me: + me = _get_ident() + if self._owner == me: self._count = self._count + 1 if __debug__: self._note("%s.acquire(%s): recursive success", self, blocking) @@ -118,7 +120,7 @@ __enter__ = acquire def release(self): - if self._owner is not current_thread(): + if self._owner != _get_ident(): raise RuntimeError("cannot release un-acquired lock") self._count = count = self._count - 1 if not count: @@ -152,7 +154,7 @@ return (count, owner) def _is_owned(self): - return self._owner is current_thread() + return self._owner == _get_ident() def Condition(*args, **kwargs): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 9 17:08:16 2009 @@ -123,6 +123,10 @@ Library ------- +- Issue #7282: Fix a memory leak when an RLock was used in a thread other + than those started through `threading.Thread` (for example, using + `_thread.start_new_thread()`). + - Issue #7187: Importlib would not silence the IOError raised when trying to write new bytecode when it was made read-only. From python-checkins at python.org Mon Nov 9 17:47:50 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 09 Nov 2009 16:47:50 -0000 Subject: [Python-checkins] r76174 - in python/branches/release26-maint: Lib/test/lock_tests.py Lib/test/test_thread.py Lib/test/test_threading.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 9 17:47:50 2009 New Revision: 76174 Log: Merged revisions 76137,76172 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76137 | antoine.pitrou | 2009-11-06 23:34:35 +0100 (ven., 06 nov. 2009) | 4 lines Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. ........ r76172 | antoine.pitrou | 2009-11-09 17:00:11 +0100 (lun., 09 nov. 2009) | 5 lines Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. ........ Added: python/branches/release26-maint/Lib/test/lock_tests.py - copied, changed from r76137, /python/trunk/Lib/test/lock_tests.py Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_thread.py python/branches/release26-maint/Lib/test/test_threading.py python/branches/release26-maint/Lib/threading.py python/branches/release26-maint/Misc/NEWS Copied: python/branches/release26-maint/Lib/test/lock_tests.py (from r76137, /python/trunk/Lib/test/lock_tests.py) ============================================================================== --- /python/trunk/Lib/test/lock_tests.py (original) +++ python/branches/release26-maint/Lib/test/lock_tests.py Mon Nov 9 17:47:50 2009 @@ -130,6 +130,19 @@ # Check the lock is unacquired Bunch(f, 1).wait_for_finished() + def test_thread_leak(self): + # The lock shouldn't leak a Thread instance when used from a foreign + # (non-threading) thread. + lock = self.locktype() + def f(): + lock.acquire() + lock.release() + n = len(threading.enumerate()) + # We run many threads in the hope that existing threads ids won't + # be recycled. + Bunch(f, 15).wait_for_finished() + self.assertEqual(n, len(threading.enumerate())) + class LockTests(BaseLockTests): """ @@ -244,8 +257,10 @@ results1 = [] results2 = [] def f(): - results1.append(evt.wait()) - results2.append(evt.wait()) + evt.wait() + results1.append(evt.is_set()) + evt.wait() + results2.append(evt.is_set()) b = Bunch(f, N) b.wait_for_started() _wait() @@ -269,9 +284,11 @@ results2 = [] N = 5 def f(): - results1.append(evt.wait(0.0)) + evt.wait(0.0) + results1.append(evt.is_set()) t1 = time.time() - r = evt.wait(0.2) + evt.wait(0.2) + r = evt.is_set() t2 = time.time() results2.append((r, t2 - t1)) Bunch(f, N).wait_for_finished() Modified: python/branches/release26-maint/Lib/test/test_thread.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_thread.py (original) +++ python/branches/release26-maint/Lib/test/test_thread.py Mon Nov 9 17:47:50 2009 @@ -5,6 +5,7 @@ import thread import time +from test import lock_tests NUMTASKS = 10 NUMTRIPS = 3 @@ -164,8 +165,12 @@ self.done_mutex.release() +class LockTests(lock_tests.LockTests): + locktype = thread.allocate_lock + + def test_main(): - test_support.run_unittest(ThreadRunningTests, BarrierTest) + test_support.run_unittest(ThreadRunningTests, BarrierTest, LockTests) if __name__ == "__main__": test_main() Modified: python/branches/release26-maint/Lib/test/test_threading.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_threading.py (original) +++ python/branches/release26-maint/Lib/test/test_threading.py Mon Nov 9 17:47:50 2009 @@ -11,6 +11,8 @@ import unittest import weakref +from test import lock_tests + # A trivial mutable counter. class Counter(object): def __init__(self): @@ -132,11 +134,9 @@ def test_foreign_thread(self): # Check that a "foreign" thread can use the threading module. def f(mutex): - # Acquiring an RLock forces an entry for the foreign + # Calling current_thread() forces an entry for the foreign # thread to get made in the threading._active map. - r = threading.RLock() - r.acquire() - r.release() + threading.current_thread() mutex.release() mutex = threading.Lock() @@ -453,22 +453,6 @@ thread.start() self.assertRaises(RuntimeError, thread.start) - def test_releasing_unacquired_rlock(self): - rlock = threading.RLock() - self.assertRaises(RuntimeError, rlock.release) - - def test_waiting_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.wait) - - def test_notify_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.notify) - - def test_semaphore_with_negative_value(self): - self.assertRaises(ValueError, threading.Semaphore, value = -1) - self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxint) - def test_joining_current_thread(self): current_thread = threading.current_thread() self.assertRaises(RuntimeError, current_thread.join); @@ -483,8 +467,34 @@ self.assertRaises(RuntimeError, setattr, thread, "daemon", True) +class LockTests(lock_tests.LockTests): + locktype = staticmethod(threading.Lock) + +class RLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading.RLock) + +class EventTests(lock_tests.EventTests): + eventtype = staticmethod(threading.Event) + +class ConditionAsRLockTests(lock_tests.RLockTests): + # An Condition uses an RLock by default and exports its API. + locktype = staticmethod(threading.Condition) + +class ConditionTests(lock_tests.ConditionTests): + condtype = staticmethod(threading.Condition) + +class SemaphoreTests(lock_tests.SemaphoreTests): + semtype = staticmethod(threading.Semaphore) + +class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): + semtype = staticmethod(threading.BoundedSemaphore) + + def test_main(): - test.test_support.run_unittest(ThreadTests, + test.test_support.run_unittest(LockTests, RLockTests, EventTests, + ConditionAsRLockTests, ConditionTests, + SemaphoreTests, BoundedSemaphoreTests, + ThreadTests, ThreadJoinOnShutdown, ThreadingExceptionTests, ) Modified: python/branches/release26-maint/Lib/threading.py ============================================================================== --- python/branches/release26-maint/Lib/threading.py (original) +++ python/branches/release26-maint/Lib/threading.py Mon Nov 9 17:47:50 2009 @@ -106,14 +106,16 @@ def __repr__(self): owner = self.__owner - return "<%s(%s, %d)>" % ( - self.__class__.__name__, - owner and owner.name, - self.__count) + try: + owner = _active[owner].name + except KeyError: + pass + return "<%s owner=%r count=%d>" % ( + self.__class__.__name__, owner, self.__count) def acquire(self, blocking=1): - me = current_thread() - if self.__owner is me: + me = _get_ident() + if self.__owner == me: self.__count = self.__count + 1 if __debug__: self._note("%s.acquire(%s): recursive success", self, blocking) @@ -132,7 +134,7 @@ __enter__ = acquire def release(self): - if self.__owner is not current_thread(): + if self.__owner != _get_ident(): raise RuntimeError("cannot release un-acquired lock") self.__count = count = self.__count - 1 if not count: @@ -168,7 +170,7 @@ return (count, owner) def _is_owned(self): - return self.__owner is current_thread() + return self.__owner == _get_ident() def Condition(*args, **kwargs): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Nov 9 17:47:50 2009 @@ -24,6 +24,10 @@ Library ------- +- Issue #7282: Fix a memory leak when an RLock was used in a thread other + than those started through `threading.Thread` (for example, using + `thread.start_new_thread()`. + - Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. @@ -71,6 +75,9 @@ Tests ----- +- Issue #7270: Add some dedicated unit tests for multi-thread synchronization + primitives such as Lock, RLock, Condition, Event and Semaphore. + - Issue #7055: test___all__ now greedily detects all modules which have an __all__ attribute, rather than using a hardcoded and incomplete list. From python-checkins at python.org Mon Nov 9 17:52:47 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 09 Nov 2009 16:52:47 -0000 Subject: [Python-checkins] r76175 - in python/branches/release31-maint: Lib/test/lock_tests.py Lib/test/test_thread.py Lib/test/test_threading.py Lib/threading.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Mon Nov 9 17:52:46 2009 New Revision: 76175 Log: Merged revisions 76138,76173 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76138 | antoine.pitrou | 2009-11-06 23:41:14 +0100 (ven., 06 nov. 2009) | 10 lines Merged revisions 76137 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76137 | antoine.pitrou | 2009-11-06 23:34:35 +0100 (ven., 06 nov. 2009) | 4 lines Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. ........ ................ r76173 | antoine.pitrou | 2009-11-09 17:08:16 +0100 (lun., 09 nov. 2009) | 11 lines Merged revisions 76172 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76172 | antoine.pitrou | 2009-11-09 17:00:11 +0100 (lun., 09 nov. 2009) | 5 lines Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. ........ ................ Added: python/branches/release31-maint/Lib/test/lock_tests.py - copied, changed from r76138, /python/branches/py3k/Lib/test/lock_tests.py Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_thread.py python/branches/release31-maint/Lib/test/test_threading.py python/branches/release31-maint/Lib/threading.py python/branches/release31-maint/Misc/NEWS Copied: python/branches/release31-maint/Lib/test/lock_tests.py (from r76138, /python/branches/py3k/Lib/test/lock_tests.py) ============================================================================== --- /python/branches/py3k/Lib/test/lock_tests.py (original) +++ python/branches/release31-maint/Lib/test/lock_tests.py Mon Nov 9 17:52:46 2009 @@ -130,6 +130,19 @@ # Check the lock is unacquired Bunch(f, 1).wait_for_finished() + def test_thread_leak(self): + # The lock shouldn't leak a Thread instance when used from a foreign + # (non-threading) thread. + lock = self.locktype() + def f(): + lock.acquire() + lock.release() + n = len(threading.enumerate()) + # We run many threads in the hope that existing threads ids won't + # be recycled. + Bunch(f, 15).wait_for_finished() + self.assertEqual(n, len(threading.enumerate())) + class LockTests(BaseLockTests): """ Modified: python/branches/release31-maint/Lib/test/test_thread.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_thread.py (original) +++ python/branches/release31-maint/Lib/test/test_thread.py Mon Nov 9 17:52:46 2009 @@ -5,6 +5,7 @@ import _thread as thread import time +from test import lock_tests NUMTASKS = 10 NUMTRIPS = 3 @@ -161,8 +162,12 @@ if finished: self.done_mutex.release() +class LockTests(lock_tests.LockTests): + locktype = thread.allocate_lock + + def test_main(): - support.run_unittest(ThreadRunningTests, BarrierTest) + support.run_unittest(ThreadRunningTests, BarrierTest, LockTests) if __name__ == "__main__": test_main() Modified: python/branches/release31-maint/Lib/test/test_threading.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_threading.py (original) +++ python/branches/release31-maint/Lib/test/test_threading.py Mon Nov 9 17:52:46 2009 @@ -11,6 +11,8 @@ import unittest import weakref +from test import lock_tests + # A trivial mutable counter. class Counter(object): def __init__(self): @@ -133,11 +135,9 @@ def test_foreign_thread(self): # Check that a "foreign" thread can use the threading module. def f(mutex): - # Acquiring an RLock forces an entry for the foreign + # Calling current_thread() forces an entry for the foreign # thread to get made in the threading._active map. - r = threading.RLock() - r.acquire() - r.release() + threading.current_thread() mutex.release() mutex = threading.Lock() @@ -471,22 +471,6 @@ thread.start() self.assertRaises(RuntimeError, thread.start) - def test_releasing_unacquired_rlock(self): - rlock = threading.RLock() - self.assertRaises(RuntimeError, rlock.release) - - def test_waiting_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.wait) - - def test_notify_on_unacquired_condition(self): - cond = threading.Condition() - self.assertRaises(RuntimeError, cond.notify) - - def test_semaphore_with_negative_value(self): - self.assertRaises(ValueError, threading.Semaphore, value = -1) - self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxsize) - def test_joining_current_thread(self): current_thread = threading.current_thread() self.assertRaises(RuntimeError, current_thread.join); @@ -501,11 +485,37 @@ self.assertRaises(RuntimeError, setattr, thread, "daemon", True) +class LockTests(lock_tests.LockTests): + locktype = staticmethod(threading.Lock) + +class RLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading.RLock) + +class EventTests(lock_tests.EventTests): + eventtype = staticmethod(threading.Event) + +class ConditionAsRLockTests(lock_tests.RLockTests): + # An Condition uses an RLock by default and exports its API. + locktype = staticmethod(threading.Condition) + +class ConditionTests(lock_tests.ConditionTests): + condtype = staticmethod(threading.Condition) + +class SemaphoreTests(lock_tests.SemaphoreTests): + semtype = staticmethod(threading.Semaphore) + +class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): + semtype = staticmethod(threading.BoundedSemaphore) + + def test_main(): - test.support.run_unittest(ThreadTests, - ThreadJoinOnShutdown, - ThreadingExceptionTests, - ) + test.support.run_unittest(LockTests, RLockTests, EventTests, + ConditionAsRLockTests, ConditionTests, + SemaphoreTests, BoundedSemaphoreTests, + ThreadTests, + ThreadJoinOnShutdown, + ThreadingExceptionTests, + ) if __name__ == "__main__": test_main() Modified: python/branches/release31-maint/Lib/threading.py ============================================================================== --- python/branches/release31-maint/Lib/threading.py (original) +++ python/branches/release31-maint/Lib/threading.py Mon Nov 9 17:52:46 2009 @@ -92,14 +92,16 @@ def __repr__(self): owner = self._owner - return "<%s(%s, %d)>" % ( - self.__class__.__name__, - owner and owner.name, - self._count) + try: + owner = _active[owner].name + except KeyError: + pass + return "<%s owner=%r count=%d>" % ( + self.__class__.__name__, owner, self._count) def acquire(self, blocking=True): - me = current_thread() - if self._owner is me: + me = _get_ident() + if self._owner == me: self._count = self._count + 1 if __debug__: self._note("%s.acquire(%s): recursive success", self, blocking) @@ -118,7 +120,7 @@ __enter__ = acquire def release(self): - if self._owner is not current_thread(): + if self._owner != _get_ident(): raise RuntimeError("cannot release un-acquired lock") self._count = count = self._count - 1 if not count: @@ -152,7 +154,7 @@ return (count, owner) def _is_owned(self): - return self._owner is current_thread() + return self._owner == _get_ident() def Condition(*args, **kwargs): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Nov 9 17:52:46 2009 @@ -40,6 +40,10 @@ Library ------- +- Issue #7282: Fix a memory leak when an RLock was used in a thread other + than those started through `threading.Thread` (for example, using + `_thread.start_new_thread()`). + - Issue #7187: Importlib would not silence the IOError raised when trying to write new bytecode when it was made read-only. @@ -140,6 +144,9 @@ Tests ----- +- Issue #7270: Add some dedicated unit tests for multi-thread synchronization + primitives such as Lock, RLock, Condition, Event and Semaphore. + - Issue #7248 (part 2): Use a unique temporary directory for importlib source tests instead of tempfile.tempdir. This prevents the tests from sharing state between concurrent executions on the same system. From python-checkins at python.org Mon Nov 9 18:03:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 17:03:34 -0000 Subject: [Python-checkins] r76176 - python/trunk/Lib/test/test_builtin.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 18:03:34 2009 New Revision: 76176 Log: Issue #7251: Break out round tests for large values into a separate test function, and skip that test on Linux/alpha systems with a broken system round function. This should turn the Debian/alpha buildbot green. Modified: python/trunk/Lib/test/test_builtin.py Modified: python/trunk/Lib/test/test_builtin.py ============================================================================== --- python/trunk/Lib/test/test_builtin.py (original) +++ python/trunk/Lib/test/test_builtin.py Mon Nov 9 18:03:34 2009 @@ -1,5 +1,6 @@ # Python test set -- built-in functions +import platform import test.test_support, unittest from test.test_support import fcmp, have_unicode, TESTFN, unlink, \ run_unittest, run_with_locale @@ -1227,9 +1228,6 @@ self.assertEqual(round(-5.5), -6) self.assertEqual(round(-6.5), -7) - # Issue #1869: integral floats should remain unchanged - self.assertEqual(round(5e15+1), 5e15+1) - # Check behavior on ints self.assertEqual(round(0), 0) self.assertEqual(round(8), 8) @@ -1262,6 +1260,27 @@ self.assertRaises(TypeError, round, t) self.assertRaises(TypeError, round, t, 0) + # Some versions of glibc for alpha have a bug that affects + # float -> integer rounding (floor, ceil, rint, round) for + # values in the range [2**52, 2**53). See: + # + # http://sources.redhat.com/bugzilla/show_bug.cgi?id=5350 + # + # We skip this test on Linux/alpha if it would fail. + linux_alpha = (platform.system().startswith('Linux') and + platform.machine().startswith('alpha')) + system_round_bug = round(5e15+1) != 5e15+1 + @unittest.skipIf(linux_alpha and system_round_bug, + "test will fail; failure is probably due to a " + "buggy system round function") + def test_round_large(self): + # Issue #1869: integral floats should remain unchanged + self.assertEqual(round(5e15-1), 5e15-1) + self.assertEqual(round(5e15), 5e15) + self.assertEqual(round(5e15+1), 5e15+1) + self.assertEqual(round(5e15+2), 5e15+2) + self.assertEqual(round(5e15+3), 5e15+3) + def test_setattr(self): setattr(sys, 'spam', 1) self.assertEqual(sys.spam, 1) From python-checkins at python.org Mon Nov 9 18:12:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 17:12:31 -0000 Subject: [Python-checkins] r76177 - in python/branches/py3k: Lib/test/test_builtin.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 18:12:30 2009 New Revision: 76177 Log: Merged revisions 76176 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76176 | mark.dickinson | 2009-11-09 17:03:34 +0000 (Mon, 09 Nov 2009) | 7 lines Issue #7251: Break out round tests for large values into a separate test function, and skip that test on Linux/alpha systems with a broken system round function. This should turn the Debian/alpha buildbot green. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_builtin.py Modified: python/branches/py3k/Lib/test/test_builtin.py ============================================================================== --- python/branches/py3k/Lib/test/test_builtin.py (original) +++ python/branches/py3k/Lib/test/test_builtin.py Mon Nov 9 18:12:30 2009 @@ -1,5 +1,6 @@ # Python test set -- built-in functions +import platform import test.support, unittest from test.support import fcmp, TESTFN, unlink, run_unittest, \ run_with_locale @@ -1123,6 +1124,27 @@ self.assertRaises(TypeError, round, t) self.assertRaises(TypeError, round, t, 0) + # Some versions of glibc for alpha have a bug that affects + # float -> integer rounding (floor, ceil, rint, round) for + # values in the range [2**52, 2**53). See: + # + # http://sources.redhat.com/bugzilla/show_bug.cgi?id=5350 + # + # We skip this test on Linux/alpha if it would fail. + linux_alpha = (platform.system().startswith('Linux') and + platform.machine().startswith('alpha')) + system_round_bug = round(5e15+1) != 5e15+1 + @unittest.skipIf(linux_alpha and system_round_bug, + "test will fail; failure is probably due to a " + "buggy system round function") + def test_round_large(self): + # Issue #1869: integral floats should remain unchanged + self.assertEqual(round(5e15-1), 5e15-1) + self.assertEqual(round(5e15), 5e15) + self.assertEqual(round(5e15+1), 5e15+1) + self.assertEqual(round(5e15+2), 5e15+2) + self.assertEqual(round(5e15+3), 5e15+3) + def test_setattr(self): setattr(sys, 'spam', 1) self.assertEqual(sys.spam, 1) From python-checkins at python.org Mon Nov 9 18:14:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 17:14:18 -0000 Subject: [Python-checkins] r76178 - in python/branches/release31-maint: Lib/test/test_builtin.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 18:14:18 2009 New Revision: 76178 Log: Merged revisions 76177 via svnmerge from svn+ssh://pythondev at www.python.org/python/branches/py3k ................ r76177 | mark.dickinson | 2009-11-09 17:12:30 +0000 (Mon, 09 Nov 2009) | 13 lines Merged revisions 76176 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76176 | mark.dickinson | 2009-11-09 17:03:34 +0000 (Mon, 09 Nov 2009) | 7 lines Issue #7251: Break out round tests for large values into a separate test function, and skip that test on Linux/alpha systems with a broken system round function. This should turn the Debian/alpha buildbot green. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_builtin.py Modified: python/branches/release31-maint/Lib/test/test_builtin.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_builtin.py (original) +++ python/branches/release31-maint/Lib/test/test_builtin.py Mon Nov 9 18:14:18 2009 @@ -1,5 +1,6 @@ # Python test set -- built-in functions +import platform import test.support, unittest from test.support import fcmp, TESTFN, unlink, run_unittest, \ run_with_locale @@ -1123,6 +1124,27 @@ self.assertRaises(TypeError, round, t) self.assertRaises(TypeError, round, t, 0) + # Some versions of glibc for alpha have a bug that affects + # float -> integer rounding (floor, ceil, rint, round) for + # values in the range [2**52, 2**53). See: + # + # http://sources.redhat.com/bugzilla/show_bug.cgi?id=5350 + # + # We skip this test on Linux/alpha if it would fail. + linux_alpha = (platform.system().startswith('Linux') and + platform.machine().startswith('alpha')) + system_round_bug = round(5e15+1) != 5e15+1 + @unittest.skipIf(linux_alpha and system_round_bug, + "test will fail; failure is probably due to a " + "buggy system round function") + def test_round_large(self): + # Issue #1869: integral floats should remain unchanged + self.assertEqual(round(5e15-1), 5e15-1) + self.assertEqual(round(5e15), 5e15) + self.assertEqual(round(5e15+1), 5e15+1) + self.assertEqual(round(5e15+2), 5e15+2) + self.assertEqual(round(5e15+3), 5e15+3) + def test_setattr(self): setattr(sys, 'spam', 1) self.assertEqual(sys.spam, 1) From python-checkins at python.org Mon Nov 9 18:45:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 17:45:40 -0000 Subject: [Python-checkins] r76179 - in python/branches/release26-maint: Lib/test/test_builtin.py Misc/NEWS Python/bltinmodule.c Message-ID: Author: mark.dickinson Date: Mon Nov 9 18:45:40 2009 New Revision: 76179 Log: Issue #7070: Fix problem with builtin round function for large odd integer arguments. Also fixes the sign of round(-0.0). Modified: python/branches/release26-maint/Lib/test/test_builtin.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Python/bltinmodule.c Modified: python/branches/release26-maint/Lib/test/test_builtin.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_builtin.py (original) +++ python/branches/release26-maint/Lib/test/test_builtin.py Mon Nov 9 18:45:40 2009 @@ -1,5 +1,6 @@ # Python test set -- built-in functions +import platform import test.test_support, unittest from test.test_support import fcmp, have_unicode, TESTFN, unlink, \ run_unittest, run_with_locale @@ -1259,6 +1260,14 @@ self.assertRaises(TypeError, round, t) self.assertRaises(TypeError, round, t, 0) + def test_round_large(self): + # Issue #1869: integral floats should remain unchanged + self.assertEqual(round(5e15-1), 5e15-1) + self.assertEqual(round(5e15), 5e15) + self.assertEqual(round(5e15+1), 5e15+1) + self.assertEqual(round(5e15+2), 5e15+2) + self.assertEqual(round(5e15+3), 5e15+3) + def test_setattr(self): setattr(sys, 'spam', 1) self.assertEqual(sys.spam, 1) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Nov 9 18:45:40 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #7070: Fix round bug for large odd integer arguments. + - Issue #7078: Set struct.__doc__ from _struct.__doc__. - Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which Modified: python/branches/release26-maint/Python/bltinmodule.c ============================================================================== --- python/branches/release26-maint/Python/bltinmodule.c (original) +++ python/branches/release26-maint/Python/bltinmodule.c Mon Nov 9 18:45:40 2009 @@ -2120,7 +2120,7 @@ static PyObject * builtin_round(PyObject *self, PyObject *args, PyObject *kwds) { - double number; + double number, abs_number, abs_result; double f; int ndigits = 0; int i; @@ -2137,10 +2137,14 @@ number /= f; else number *= f; - if (number >= 0.0) - number = floor(number + 0.5); - else - number = ceil(number - 0.5); + + /* round `number` to nearest integer, rounding halves away from zero */ + abs_number = fabs(number); + abs_result = floor(abs_number); + if (abs_number - abs_result >= 0.5) + abs_result += 1.0; + number = copysign(abs_result, number); + if (ndigits < 0) number *= f; else From python-checkins at python.org Mon Nov 9 18:53:38 2009 From: python-checkins at python.org (guido.van.rossum) Date: Mon, 09 Nov 2009 17:53:38 -0000 Subject: [Python-checkins] r76180 - peps/trunk/pep-3003.txt Message-ID: Author: guido.van.rossum Date: Mon Nov 9 18:53:38 2009 New Revision: 76180 Log: Clarify the time covered by the moratorium. Also explicitly say an extension would require another PEP. Modified: peps/trunk/pep-3003.txt Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Mon Nov 9 18:53:38 2009 @@ -15,7 +15,10 @@ This PEP proposes a temporary moratorium (suspension) of all changes to the Python language syntax, semantics, and built-ins for a period -of at least two years from the release of Python 3.1. +of at least two years from the release of Python 3.1. In particular, the +moratorium would include Python 3.2 (to be released 18-24 months after +3.1) but allow Python 3.3 (assuming it is not released prematurely) to +once again include language changes. This suspension of features is designed to allow non-CPython implementations to "catch up" to the core implementation of the language, help ease adoption @@ -133,6 +136,12 @@ commits would need to be rolled back in order to meet this goal. +Extensions +========== + +The time period of the moratorium can only be extended through a new PEP. + + Copyright ========= From python-checkins at python.org Mon Nov 9 18:54:51 2009 From: python-checkins at python.org (guido.van.rossum) Date: Mon, 09 Nov 2009 17:54:51 -0000 Subject: [Python-checkins] r76181 - peps/trunk/pep-3003.txt Message-ID: Author: guido.van.rossum Date: Mon Nov 9 18:54:51 2009 New Revision: 76181 Log: Accept the moratorium. Also add Nov 3 to the post history. Modified: peps/trunk/pep-3003.txt Modified: peps/trunk/pep-3003.txt ============================================================================== --- peps/trunk/pep-3003.txt (original) +++ peps/trunk/pep-3003.txt Mon Nov 9 18:54:51 2009 @@ -3,11 +3,11 @@ Version: $Revision$ Last-Modified: $Date$ Author: Brett Cannon, Jesse Noller, Guido van Rossum -Status: Draft +Status: Accepted Type: Process Content-Type: text/x-rst Created: 21-Oct-2009 -Post-History: +Post-History: 03-Nov-2009 Abstract From python-checkins at python.org Mon Nov 9 20:54:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 19:54:51 -0000 Subject: [Python-checkins] r76182 - python/trunk/Lib/test/test_signal.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 20:54:51 2009 New Revision: 76182 Log: Add extra information to a test_signal failure message to aid diagnosis of buildbot failure. Modified: python/trunk/Lib/test/test_signal.py Modified: python/trunk/Lib/test/test_signal.py ============================================================================== --- python/trunk/Lib/test/test_signal.py (original) +++ python/trunk/Lib/test/test_signal.py Mon Nov 9 20:54:51 2009 @@ -367,7 +367,9 @@ if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_vtalrm handler stopped this itimer else: - self.fail('timeout waiting for sig_vtalrm signal') + self.fail('timeout waiting for sig_vtalrm signal; ' + 'signal.getitimer(self.itimer) gives: %s' % + (signal.getitimer(self.itimer),)) # virtual itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) From python-checkins at python.org Mon Nov 9 20:59:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 19:59:08 -0000 Subject: [Python-checkins] r76183 - in python/branches/release26-maint: Lib/test/test_signal.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 20:59:08 2009 New Revision: 76183 Log: Merged revisions 76182 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76182 | mark.dickinson | 2009-11-09 19:54:51 +0000 (Mon, 09 Nov 2009) | 1 line Add extra information to a test_signal failure message to aid diagnosis of buildbot failure. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_signal.py Modified: python/branches/release26-maint/Lib/test/test_signal.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_signal.py (original) +++ python/branches/release26-maint/Lib/test/test_signal.py Mon Nov 9 20:59:08 2009 @@ -367,7 +367,9 @@ if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_vtalrm handler stopped this itimer else: - self.fail('timeout waiting for sig_vtalrm signal') + self.fail('timeout waiting for sig_vtalrm signal; ' + 'signal.getitimer(self.itimer) gives: %s' % + (signal.getitimer(self.itimer),)) # virtual itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) From python-checkins at python.org Mon Nov 9 21:00:39 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 20:00:39 -0000 Subject: [Python-checkins] r76184 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Nov 9 21:00:39 2009 New Revision: 76184 Log: Blocked revisions 76176 via svnmerge ........ r76176 | mark.dickinson | 2009-11-09 17:03:34 +0000 (Mon, 09 Nov 2009) | 7 lines Issue #7251: Break out round tests for large values into a separate test function, and skip that test on Linux/alpha systems with a broken system round function. This should turn the Debian/alpha buildbot green. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 9 21:08:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 20:08:57 -0000 Subject: [Python-checkins] r76185 - in python/branches/py3k: Lib/test/test_signal.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 21:08:57 2009 New Revision: 76185 Log: Merged revisions 76182 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76182 | mark.dickinson | 2009-11-09 19:54:51 +0000 (Mon, 09 Nov 2009) | 1 line Add extra information to a test_signal failure message to aid diagnosis of buildbot failure. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_signal.py Modified: python/branches/py3k/Lib/test/test_signal.py ============================================================================== --- python/branches/py3k/Lib/test/test_signal.py (original) +++ python/branches/py3k/Lib/test/test_signal.py Mon Nov 9 21:08:57 2009 @@ -367,7 +367,9 @@ if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_vtalrm handler stopped this itimer else: - self.fail('timeout waiting for sig_vtalrm signal') + self.fail('timeout waiting for sig_vtalrm signal; ' + 'signal.getitimer(self.itimer) gives: %s' % + (signal.getitimer(self.itimer),)) # virtual itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) From python-checkins at python.org Mon Nov 9 21:10:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 09 Nov 2009 20:10:02 -0000 Subject: [Python-checkins] r76186 - in python/branches/release31-maint: Lib/test/test_signal.py Message-ID: Author: mark.dickinson Date: Mon Nov 9 21:10:01 2009 New Revision: 76186 Log: Merged revisions 76185 via svnmerge from svn+ssh://pythondev at www.python.org/python/branches/py3k ................ r76185 | mark.dickinson | 2009-11-09 20:08:57 +0000 (Mon, 09 Nov 2009) | 9 lines Merged revisions 76182 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76182 | mark.dickinson | 2009-11-09 19:54:51 +0000 (Mon, 09 Nov 2009) | 1 line Add extra information to a test_signal failure message to aid diagnosis of buildbot failure. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_signal.py Modified: python/branches/release31-maint/Lib/test/test_signal.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_signal.py (original) +++ python/branches/release31-maint/Lib/test/test_signal.py Mon Nov 9 21:10:01 2009 @@ -367,7 +367,9 @@ if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_vtalrm handler stopped this itimer else: - self.fail('timeout waiting for sig_vtalrm signal') + self.fail('timeout waiting for sig_vtalrm signal; ' + 'signal.getitimer(self.itimer) gives: %s' % + (signal.getitimer(self.itimer),)) # virtual itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) From solipsis at pitrou.net Mon Nov 9 22:24:59 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 9 Nov 2009 22:24:59 +0100 (CET) Subject: [Python-checkins] py3k (r76177) reference leaks: sum=23 Message-ID: <20091109212459.C0C6317882@ns6635.ovh.net> py3k results for svn r76177 (hg cset 53ea73f56597) -------------------------------------------------- test_urllib leaked [6, 4, 6] references, sum=16 From solipsis at pitrou.net Mon Nov 9 23:08:15 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Mon, 9 Nov 2009 22:08:15 +0000 (UTC) Subject: [Python-checkins] py3k (r76177) reference leaks: sum=23 References: <20091109212459.C0C6317882@ns6635.ovh.net> Message-ID: pitrou.net> writes: > > py3k results for svn r76177 (hg cset 53ea73f56597) > -------------------------------------------------- > > test_urllib leaked [6, 4, 6] references, sum=16 Ok, there's obviously a little arithmetic problem in the computation of "sum" in the message subject :) From nnorwitz at gmail.com Mon Nov 9 23:59:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 9 Nov 2009 17:59:55 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091109225955.GA12601@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 0, -81] references, sum=-81 test_zipimport_support leaked [0, 25, 0] references, sum=25 Less important issues: ---------------------- From solipsis at pitrou.net Tue Nov 10 04:01:27 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 10 Nov 2009 04:01:27 +0100 (CET) Subject: [Python-checkins] py3k (r76185) reference leaks: sum=16 Message-ID: <20091110030127.5FAEB1771C@ns6635.ovh.net> py3k results for svn r76185 (hg cset 86658db02ce1) -------------------------------------------------- test_urllib leaked [6, 4, 6] references, sum=16 From python-checkins at python.org Tue Nov 10 19:21:06 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2009 18:21:06 -0000 Subject: [Python-checkins] r76187 - python/branches/release31-maint/Doc/library/collections.rst Message-ID: Author: raymond.hettinger Date: Tue Nov 10 19:21:06 2009 New Revision: 76187 Log: Show example of how to make a sorted dictionary Modified: python/branches/release31-maint/Doc/library/collections.rst Modified: python/branches/release31-maint/Doc/library/collections.rst ============================================================================== --- python/branches/release31-maint/Doc/library/collections.rst (original) +++ python/branches/release31-maint/Doc/library/collections.rst Tue Nov 10 19:21:06 2009 @@ -862,6 +862,28 @@ `Equivalent OrderedDict recipe `_ that runs on Python 2.4 or later. +Since an ordered dictionary remembers its insertion order, it can be used +in conjuction with sorting to make a sorted dictionary:: + + >>> # regular unsorted dictionary + >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} + + >>> # dictionary sorted by key + >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) + OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) + + >>> # dictionary sorted by value + >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) + OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) + + >>> # dictionary sorted by length of the key string + >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) + OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)]) + +The new sorted dictionaries maintain their sort order when entries +are deleted. But when new keys are added, the keys are appended +to the end and the sort is not maintained. + :class:`UserDict` objects ------------------------- From python-checkins at python.org Tue Nov 10 19:35:46 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2009 18:35:46 -0000 Subject: [Python-checkins] r76188 - python/branches/py3k/Doc/library/collections.rst Message-ID: Author: raymond.hettinger Date: Tue Nov 10 19:35:46 2009 New Revision: 76188 Log: Show example of how to make a sorted dictionary Modified: python/branches/py3k/Doc/library/collections.rst Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Tue Nov 10 19:35:46 2009 @@ -862,6 +862,28 @@ `Equivalent OrderedDict recipe `_ that runs on Python 2.4 or later. +Since an ordered dictionary remembers its insertion order, it can be used +in conjuction with sorting to make a sorted dictionary:: + + >>> # regular unsorted dictionary + >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} + + >>> # dictionary sorted by key + >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) + OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) + + >>> # dictionary sorted by value + >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) + OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) + + >>> # dictionary sorted by length of the key string + >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) + OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)]) + +The new sorted dictionaries maintain their sort order when entries +are deleted. But when new keys are added, the keys are appended +to the end and the sort is not maintained. + :class:`UserDict` objects ------------------------- From python-checkins at python.org Tue Nov 10 19:46:02 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 18:46:02 -0000 Subject: [Python-checkins] r76189 - in python/branches/py3k: Lib/test/test_threading.py Lib/threading.py Misc/NEWS Modules/_threadmodule.c Message-ID: Author: antoine.pitrou Date: Tue Nov 10 19:46:01 2009 New Revision: 76189 Log: Issue #3001: Add a C implementation of recursive locks which is used by default when instantiating a `Threading.RLock` object. This makes recursive locks as fast as regular non-recursive locks (previously, they were slower by 10x to 15x). Modified: python/branches/py3k/Lib/test/test_threading.py python/branches/py3k/Lib/threading.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_threadmodule.c Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Tue Nov 10 19:46:01 2009 @@ -506,8 +506,11 @@ class LockTests(lock_tests.LockTests): locktype = staticmethod(threading.Lock) -class RLockTests(lock_tests.RLockTests): - locktype = staticmethod(threading.RLock) +class PyRLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading._PyRLock) + +class CRLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading._CRLock) class EventTests(lock_tests.EventTests): eventtype = staticmethod(threading.Event) @@ -527,7 +530,7 @@ def test_main(): - test.support.run_unittest(LockTests, RLockTests, EventTests, + test.support.run_unittest(LockTests, PyRLockTests, CRLockTests, EventTests, ConditionAsRLockTests, ConditionTests, SemaphoreTests, BoundedSemaphoreTests, ThreadTests, Modified: python/branches/py3k/Lib/threading.py ============================================================================== --- python/branches/py3k/Lib/threading.py (original) +++ python/branches/py3k/Lib/threading.py Tue Nov 10 19:46:01 2009 @@ -27,6 +27,10 @@ _allocate_lock = _thread.allocate_lock _get_ident = _thread.get_ident ThreadError = _thread.error +try: + _CRLock = _thread.RLock +except AttributeError: + _CRLock = None del _thread @@ -79,8 +83,12 @@ Lock = _allocate_lock -def RLock(*args, **kwargs): - return _RLock(*args, **kwargs) +def RLock(verbose=None, *args, **kwargs): + if verbose is None: + verbose = _VERBOSE + if (__debug__ and verbose) or _CRLock is None: + return _PyRLock(verbose, *args, **kwargs) + return _CRLock(*args, **kwargs) class _RLock(_Verbose): @@ -156,6 +164,8 @@ def _is_owned(self): return self._owner == _get_ident() +_PyRLock = _RLock + def Condition(*args, **kwargs): return _Condition(*args, **kwargs) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Nov 10 19:46:01 2009 @@ -123,6 +123,11 @@ Library ------- +- Issue #3001: Add a C implementation of recursive locks which is used by + default when instantiating a `threading.RLock` object. This makes + recursive locks as fast as regular non-recursive locks (previously, + they were slower by 10x to 15x). + - Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `_thread.start_new_thread()`). Modified: python/branches/py3k/Modules/_threadmodule.c ============================================================================== --- python/branches/py3k/Modules/_threadmodule.c (original) +++ python/branches/py3k/Modules/_threadmodule.c Tue Nov 10 19:46:01 2009 @@ -155,6 +155,273 @@ lock_methods, /*tp_methods*/ }; +/* Recursive lock objects */ + +typedef struct { + PyObject_HEAD + PyThread_type_lock rlock_lock; + long rlock_owner; + unsigned long rlock_count; + PyObject *in_weakreflist; +} rlockobject; + +static void +rlock_dealloc(rlockobject *self) +{ + assert(self->rlock_lock); + if (self->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + /* Unlock the lock so it's safe to free it */ + if (self->rlock_count > 0) + PyThread_release_lock(self->rlock_lock); + + PyThread_free_lock(self->rlock_lock); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) +{ + char *kwlist[] = {"blocking", NULL}; + int blocking = 1; + long tid; + int r = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:acquire", kwlist, + &blocking)) + return NULL; + + tid = PyThread_get_thread_ident(); + if (self->rlock_count > 0 && tid == self->rlock_owner) { + unsigned long count = self->rlock_count + 1; + if (count <= self->rlock_count) { + PyErr_SetString(PyExc_OverflowError, + "Internal lock count overflowed"); + return NULL; + } + self->rlock_count = count; + Py_RETURN_TRUE; + } + + if (self->rlock_count > 0 || + !PyThread_acquire_lock(self->rlock_lock, 0)) { + if (!blocking) { + Py_RETURN_FALSE; + } + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock(self->rlock_lock, blocking); + Py_END_ALLOW_THREADS + } + if (r) { + assert(self->rlock_count == 0); + self->rlock_owner = tid; + self->rlock_count = 1; + } + + return PyBool_FromLong(r); +} + +PyDoc_STRVAR(rlock_acquire_doc, +"acquire(blocking=True) -> bool\n\ +\n\ +Lock the lock. `blocking` indicates whether we should wait\n\ +for the lock to be available or not. If `blocking` is False\n\ +and another thread holds the lock, the method will return False\n\ +immediately. If `blocking` is True and another thread holds\n\ +the lock, the method will wait for the lock to be released,\n\ +take it and then return True.\n\ +(note: the blocking operation is not interruptible.)\n\ +\n\ +In all other cases, the method will return True immediately.\n\ +Precisely, if the current thread already holds the lock, its\n\ +internal counter is simply incremented. If nobody holds the lock,\n\ +the lock is taken and its internal counter initialized to 1."); + +static PyObject * +rlock_release(rlockobject *self) +{ + long tid = PyThread_get_thread_ident(); + + if (self->rlock_count == 0 || self->rlock_owner != tid) { + PyErr_SetString(PyExc_RuntimeError, + "cannot release un-acquired lock"); + return NULL; + } + if (--self->rlock_count == 0) { + self->rlock_owner = 0; + PyThread_release_lock(self->rlock_lock); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(rlock_release_doc, +"release()\n\ +\n\ +Release the lock, allowing another thread that is blocked waiting for\n\ +the lock to acquire the lock. The lock must be in the locked state,\n\ +and must be locked by the same thread that unlocks it; otherwise a\n\ +`RuntimeError` is raised.\n\ +\n\ +Do note that if the lock was acquire()d several times in a row by the\n\ +current thread, release() needs to be called as many times for the lock\n\ +to be available for other threads."); + +static PyObject * +rlock_acquire_restore(rlockobject *self, PyObject *arg) +{ + long owner; + unsigned long count; + int r = 1; + + if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner)) + return NULL; + + if (!PyThread_acquire_lock(self->rlock_lock, 0)) { + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock(self->rlock_lock, 1); + Py_END_ALLOW_THREADS + } + if (!r) { + PyErr_SetString(ThreadError, "couldn't acquire lock"); + return NULL; + } + assert(self->rlock_count == 0); + self->rlock_owner = owner; + self->rlock_count = count; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(rlock_acquire_restore_doc, +"_acquire_restore(state) -> None\n\ +\n\ +For internal use by `threading.Condition`."); + +static PyObject * +rlock_release_save(rlockobject *self) +{ + long owner; + unsigned long count; + + owner = self->rlock_owner; + count = self->rlock_count; + self->rlock_count = 0; + self->rlock_owner = 0; + PyThread_release_lock(self->rlock_lock); + return Py_BuildValue("kl", count, owner); +} + +PyDoc_STRVAR(rlock_release_save_doc, +"_release_save() -> tuple\n\ +\n\ +For internal use by `threading.Condition`."); + + +static PyObject * +rlock_is_owned(rlockobject *self) +{ + long tid = PyThread_get_thread_ident(); + + if (self->rlock_count > 0 && self->rlock_owner == tid) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(rlock_is_owned_doc, +"_is_owned() -> bool\n\ +\n\ +For internal use by `threading.Condition`."); + +static PyObject * +rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + rlockobject *self; + + self = (rlockobject *) type->tp_alloc(type, 0); + if (self != NULL) { + self->rlock_lock = PyThread_allocate_lock(); + if (self->rlock_lock == NULL) { + type->tp_free(self); + PyErr_SetString(ThreadError, "can't allocate lock"); + return NULL; + } + self->in_weakreflist = NULL; + self->rlock_owner = 0; + self->rlock_count = 0; + } + + return (PyObject *) self; +} + +static PyObject * +rlock_repr(rlockobject *self) +{ + return PyUnicode_FromFormat("<%s owner=%ld count=%lu>", + Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count); +} + + +static PyMethodDef rlock_methods[] = { + {"acquire", (PyCFunction)rlock_acquire, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"release", (PyCFunction)rlock_release, + METH_NOARGS, rlock_release_doc}, + {"_is_owned", (PyCFunction)rlock_is_owned, + METH_NOARGS, rlock_is_owned_doc}, + {"_acquire_restore", (PyCFunction)rlock_acquire_restore, + METH_O, rlock_acquire_restore_doc}, + {"_release_save", (PyCFunction)rlock_release_save, + METH_NOARGS, rlock_release_save_doc}, + {"__enter__", (PyCFunction)rlock_acquire, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"__exit__", (PyCFunction)rlock_release, + METH_VARARGS, rlock_release_doc}, + {NULL, NULL} /* sentinel */ +}; + + +static PyTypeObject RLocktype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_thread.RLock", /*tp_name*/ + sizeof(rlockobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)rlock_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + (reprfunc)rlock_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + rlock_methods, /*tp_methods*/ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + rlock_new /* tp_new */ +}; + static lockobject * newlockobject(void) { @@ -752,6 +1019,8 @@ return NULL; if (PyType_Ready(&Locktype) < 0) return NULL; + if (PyType_Ready(&RLocktype) < 0) + return NULL; /* Create the module and add the functions */ m = PyModule_Create(&threadmodule); @@ -766,6 +1035,10 @@ Py_INCREF(&Locktype); PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); + Py_INCREF(&RLocktype); + if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0) + return NULL; + Py_INCREF(&localtype); if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) return NULL; From python-checkins at python.org Tue Nov 10 19:58:02 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 10 Nov 2009 18:58:02 -0000 Subject: [Python-checkins] r76190 - python/trunk/Doc/faq/programming.rst Message-ID: Author: r.david.murray Date: Tue Nov 10 19:58:02 2009 New Revision: 76190 Log: Update the FAQ entry that explains that assignments in the local scope shadow variables in the outer scope (issue 7290). Modified: python/trunk/Doc/faq/programming.rst Modified: python/trunk/Doc/faq/programming.rst ============================================================================== --- python/trunk/Doc/faq/programming.rst (original) +++ python/trunk/Doc/faq/programming.rst Tue Nov 10 19:58:02 2009 @@ -277,39 +277,77 @@ Core Language ============= -How do you set a global variable in a function? ------------------------------------------------ - -Did you do something like this? :: - - x = 1 # make a global - - def f(): - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 - -Any variable assigned in a function is local to that function. unless it is -specifically declared global. Since a value is bound to ``x`` as the last -statement of the function body, the compiler assumes that ``x`` is -local. Consequently the ``print x`` attempts to print an uninitialized local -variable and will trigger a ``NameError``. - -The solution is to insert an explicit global declaration at the start of the -function:: - - def f(): - global x - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 +Why am I getting an UnboundLocalError when the variable has a value? +-------------------------------------------------------------------- -In this case, all references to ``x`` are interpreted as references to the ``x`` -from the module namespace. +It can be a surprise to get the UnboundLocalError in previously working +code when it is modified by adding an assignment statement somewhere in +the body of a function. + +This code: + + >>> x = 10 + >>> def bar(): + ... print x + >>> bar() + 10 + +works, but this code: + + >>> x = 10 + >>> def foo(): + ... print x + ... x += 1 + +results in an UnboundLocalError: + + >>> foo() + Traceback (most recent call last): + ... + UnboundLocalError: local variable 'x' referenced before assignment + +This is because when you make an assignment to a variable in a scope, that +variable becomes local to that scope and shadows any similarly named variable +in the outer scope. Since the last statement in foo assigns a new value to +``x``, the compiler recognizes it as a local variable. Consequently when the +earlier ``print x`` attempts to print the uninitialized local variable and +an error results. + +In the example above you can access the outer scope variable by declaring it +global: + + >>> x = 10 + >>> def foobar(): + ... global x + ... print x + ... x += 1 + >>> foobar() + 10 + +This explicit declaration is required in order to remind you that (unlike the +superficially analogous situation with class and instance variables) you are +actually modifying the value of the variable in the outer scope: + + >>> print x + 11 + +In Python3, you can do a similar thing in a nested scope using the +:keyword:`nonlocal` keyword: + +.. doctest:: + :options: +SKIP + + >>> def foo(): + ... x = 10 + ... def bar(): + ... nonlocal x + ... print x + ... x += 1 + ... bar() + ... print x + >>> foo() + 10 + 11 What are the rules for local and global variables in Python? From python-checkins at python.org Tue Nov 10 20:16:31 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 19:16:31 -0000 Subject: [Python-checkins] r76191 - in sandbox/trunk/newgil: Doc/library/collections.rst Doc/library/csv.rst Lib/importlib/_bootstrap.py Lib/importlib/test/source/test_file_loader.py Lib/subprocess.py Lib/test/lock_tests.py Lib/test/test_builtin.py Lib/test/test_signal.py Lib/test/test_threading.py Lib/threading.py Misc/ACKS Misc/NEWS Misc/Vim/vimrc Modules/_threadmodule.c Tools/scripts/db2pickle.py Tools/scripts/pickle2db.py Tools/scripts/redemo.py Tools/scripts/win_add2path.py Message-ID: Author: antoine.pitrou Date: Tue Nov 10 20:16:31 2009 New Revision: 76191 Log: Merged revisions 76146,76149,76155-76156,76158,76165,76170,76173,76177,76185,76188-76189 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76146 | brett.cannon | 2009-11-08 00:55:05 +0100 (dim., 08 nov. 2009) | 6 lines When trying to write new bytecode, importlib was not catching the IOError thrown if the file happened to be read-only to keep the failure silent. Fixes issue #7187. Thanks, Dave Malcolm for the report and analysis of the problem. ................ r76149 | antoine.pitrou | 2009-11-08 01:30:04 +0100 (dim., 08 nov. 2009) | 11 lines Merged revisions 76148 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76148 | antoine.pitrou | 2009-11-08 01:24:12 +0100 (dim., 08 nov. 2009) | 4 lines Kill a small potential leak in test_threading. The leak may not manifest itself if the OS re-uses the same thread ids (I suppose Neal's machine doesn't :-)) ........ ................ r76155 | brett.cannon | 2009-11-08 22:41:27 +0100 (dim., 08 nov. 2009) | 10 lines Blocked revisions 76154 via svnmerge ........ r76154 | brett.cannon | 2009-11-08 13:35:28 -0800 (Sun, 08 Nov 2009) | 4 lines Properly detect whether a C file is using tabs or spaces for Vim. Closes issue #5611. Thanks Kirk McDonald and Johannes Hoff. ........ ................ r76156 | benjamin.peterson | 2009-11-09 01:42:58 +0100 (lun., 09 nov. 2009) | 1 line fix some imports ................ r76158 | benjamin.peterson | 2009-11-09 01:49:19 +0100 (lun., 09 nov. 2009) | 1 line convert to use print() function ................ r76165 | r.david.murray | 2009-11-09 15:21:38 +0100 (lun., 09 nov. 2009) | 9 lines Merged revisions 76163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76163 | r.david.murray | 2009-11-09 09:18:14 -0500 (Mon, 09 Nov 2009) | 2 lines Remove redundant sentence. ........ ................ r76170 | eric.smith | 2009-11-09 16:23:15 +0100 (lun., 09 nov. 2009) | 9 lines Merged revisions 76168 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76168 | eric.smith | 2009-11-09 10:16:23 -0500 (Mon, 09 Nov 2009) | 1 line Issue 7294: Fixed URL in a comment. ........ ................ r76173 | antoine.pitrou | 2009-11-09 17:08:16 +0100 (lun., 09 nov. 2009) | 11 lines Merged revisions 76172 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76172 | antoine.pitrou | 2009-11-09 17:00:11 +0100 (lun., 09 nov. 2009) | 5 lines Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. ........ ................ r76177 | mark.dickinson | 2009-11-09 18:12:30 +0100 (lun., 09 nov. 2009) | 13 lines Merged revisions 76176 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76176 | mark.dickinson | 2009-11-09 17:03:34 +0000 (Mon, 09 Nov 2009) | 7 lines Issue #7251: Break out round tests for large values into a separate test function, and skip that test on Linux/alpha systems with a broken system round function. This should turn the Debian/alpha buildbot green. ........ ................ r76185 | mark.dickinson | 2009-11-09 21:08:57 +0100 (lun., 09 nov. 2009) | 9 lines Merged revisions 76182 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76182 | mark.dickinson | 2009-11-09 19:54:51 +0000 (Mon, 09 Nov 2009) | 1 line Add extra information to a test_signal failure message to aid diagnosis of buildbot failure. ........ ................ r76188 | raymond.hettinger | 2009-11-10 19:35:46 +0100 (mar., 10 nov. 2009) | 1 line Show example of how to make a sorted dictionary ................ r76189 | antoine.pitrou | 2009-11-10 19:46:01 +0100 (mar., 10 nov. 2009) | 6 lines Issue #3001: Add a C implementation of recursive locks which is used by default when instantiating a `Threading.RLock` object. This makes recursive locks as fast as regular non-recursive locks (previously, they were slower by 10x to 15x). ................ Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Doc/library/collections.rst sandbox/trunk/newgil/Doc/library/csv.rst sandbox/trunk/newgil/Lib/importlib/_bootstrap.py sandbox/trunk/newgil/Lib/importlib/test/source/test_file_loader.py sandbox/trunk/newgil/Lib/subprocess.py sandbox/trunk/newgil/Lib/test/lock_tests.py sandbox/trunk/newgil/Lib/test/test_builtin.py sandbox/trunk/newgil/Lib/test/test_signal.py sandbox/trunk/newgil/Lib/test/test_threading.py sandbox/trunk/newgil/Lib/threading.py sandbox/trunk/newgil/Misc/ACKS sandbox/trunk/newgil/Misc/NEWS sandbox/trunk/newgil/Misc/Vim/vimrc sandbox/trunk/newgil/Modules/_threadmodule.c sandbox/trunk/newgil/Tools/scripts/db2pickle.py sandbox/trunk/newgil/Tools/scripts/pickle2db.py sandbox/trunk/newgil/Tools/scripts/redemo.py sandbox/trunk/newgil/Tools/scripts/win_add2path.py Modified: sandbox/trunk/newgil/Doc/library/collections.rst ============================================================================== --- sandbox/trunk/newgil/Doc/library/collections.rst (original) +++ sandbox/trunk/newgil/Doc/library/collections.rst Tue Nov 10 20:16:31 2009 @@ -862,6 +862,28 @@ `Equivalent OrderedDict recipe `_ that runs on Python 2.4 or later. +Since an ordered dictionary remembers its insertion order, it can be used +in conjuction with sorting to make a sorted dictionary:: + + >>> # regular unsorted dictionary + >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} + + >>> # dictionary sorted by key + >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) + OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) + + >>> # dictionary sorted by value + >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) + OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) + + >>> # dictionary sorted by length of the key string + >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) + OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)]) + +The new sorted dictionaries maintain their sort order when entries +are deleted. But when new keys are added, the keys are appended +to the end and the sort is not maintained. + :class:`UserDict` objects ------------------------- Modified: sandbox/trunk/newgil/Doc/library/csv.rst ============================================================================== --- sandbox/trunk/newgil/Doc/library/csv.rst (original) +++ sandbox/trunk/newgil/Doc/library/csv.rst Tue Nov 10 20:16:31 2009 @@ -141,13 +141,12 @@ Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has fewer fields than - the fieldnames sequence, the value of *restval* will be used as the default - value. If the row read has more fields than the fieldnames sequence, the - remaining data is added as a sequence keyed by the value of *restkey*. If the - row read has fewer fields than the fieldnames sequence, the remaining keys take - the value of the optional *restval* parameter. Any other optional or keyword - arguments are passed to the underlying :class:`reader` instance. + *csvfile* will be used as the fieldnames. If the row read has more fields + than the fieldnames sequence, the remaining data is added as a sequence + keyed by the value of *restkey*. If the row read has fewer fields than the + fieldnames sequence, the remaining keys take the value of the optional + *restval* parameter. Any other optional or keyword arguments are passed to + the underlying :class:`reader` instance. .. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) Modified: sandbox/trunk/newgil/Lib/importlib/_bootstrap.py ============================================================================== --- sandbox/trunk/newgil/Lib/importlib/_bootstrap.py (original) +++ sandbox/trunk/newgil/Lib/importlib/_bootstrap.py Tue Nov 10 20:16:31 2009 @@ -526,9 +526,9 @@ bytecode_path = self.bytecode_path(name) if not bytecode_path: bytecode_path = self._base_path + _suffix_list(imp.PY_COMPILED)[0] - file = _io.FileIO(bytecode_path, 'w') # Assuming bytes. try: - with _closing(file) as bytecode_file: + # Assuming bytes. + with _closing(_io.FileIO(bytecode_path, 'w')) as bytecode_file: bytecode_file.write(data) return True except IOError as exc: Modified: sandbox/trunk/newgil/Lib/importlib/test/source/test_file_loader.py ============================================================================== --- sandbox/trunk/newgil/Lib/importlib/test/source/test_file_loader.py (original) +++ sandbox/trunk/newgil/Lib/importlib/test/source/test_file_loader.py Tue Nov 10 20:16:31 2009 @@ -6,6 +6,7 @@ import imp import os import py_compile +import stat import sys import unittest @@ -121,6 +122,10 @@ But if the marshal data is bad, even if the magic number and timestamp work, a ValueError is raised and the source is not used [bad marshal]. + The case of not being able to write out the bytecode must also be handled + as it's possible it was made read-only. In that instance the attempt to + write the bytecode should fail silently [bytecode read-only]. + """ def import_(self, file, module_name): @@ -159,6 +164,7 @@ self.assertEqual(bytecode_file.read(4), source_timestamp) # [bad marshal] + @source_util.writes_bytecode_files def test_bad_marshal(self): with source_util.create_modules('_temp') as mapping: bytecode_path = source_util.bytecode_path(mapping['_temp']) @@ -172,6 +178,26 @@ self.import_(mapping['_temp'], '_temp') self.assertTrue('_temp' not in sys.modules) + # [bytecode read-only] + @source_util.writes_bytecode_files + def test_read_only_bytecode(self): + with source_util.create_modules('_temp') as mapping: + # Create bytecode that will need to be re-created. + py_compile.compile(mapping['_temp']) + bytecode_path = source_util.bytecode_path(mapping['_temp']) + with open(bytecode_path, 'r+b') as bytecode_file: + bytecode_file.seek(0) + bytecode_file.write(b'\x00\x00\x00\x00') + # Make the bytecode read-only. + os.chmod(bytecode_path, + stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + try: + # Should not raise IOError! + self.import_(mapping['_temp'], '_temp') + finally: + # Make writable for eventual clean-up. + os.chmod(bytecode_path, stat.S_IWUSR) + def test_main(): from test.support import run_unittest Modified: sandbox/trunk/newgil/Lib/subprocess.py ============================================================================== --- sandbox/trunk/newgil/Lib/subprocess.py (original) +++ sandbox/trunk/newgil/Lib/subprocess.py Tue Nov 10 20:16:31 2009 @@ -497,7 +497,9 @@ """ # See - # http://msdn.microsoft.com/library/en-us/vccelng/htm/progs_12.asp + # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + # or search http://msdn.microsoft.com for + # "Parsing C++ Command-Line Arguments" result = [] needquote = False for arg in seq: Modified: sandbox/trunk/newgil/Lib/test/lock_tests.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/lock_tests.py (original) +++ sandbox/trunk/newgil/Lib/test/lock_tests.py Tue Nov 10 20:16:31 2009 @@ -130,6 +130,19 @@ # Check the lock is unacquired Bunch(f, 1).wait_for_finished() + def test_thread_leak(self): + # The lock shouldn't leak a Thread instance when used from a foreign + # (non-threading) thread. + lock = self.locktype() + def f(): + lock.acquire() + lock.release() + n = len(threading.enumerate()) + # We run many threads in the hope that existing threads ids won't + # be recycled. + Bunch(f, 15).wait_for_finished() + self.assertEqual(n, len(threading.enumerate())) + class LockTests(BaseLockTests): """ Modified: sandbox/trunk/newgil/Lib/test/test_builtin.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_builtin.py (original) +++ sandbox/trunk/newgil/Lib/test/test_builtin.py Tue Nov 10 20:16:31 2009 @@ -1,5 +1,6 @@ # Python test set -- built-in functions +import platform import test.support, unittest from test.support import fcmp, TESTFN, unlink, run_unittest, \ run_with_locale @@ -1123,6 +1124,27 @@ self.assertRaises(TypeError, round, t) self.assertRaises(TypeError, round, t, 0) + # Some versions of glibc for alpha have a bug that affects + # float -> integer rounding (floor, ceil, rint, round) for + # values in the range [2**52, 2**53). See: + # + # http://sources.redhat.com/bugzilla/show_bug.cgi?id=5350 + # + # We skip this test on Linux/alpha if it would fail. + linux_alpha = (platform.system().startswith('Linux') and + platform.machine().startswith('alpha')) + system_round_bug = round(5e15+1) != 5e15+1 + @unittest.skipIf(linux_alpha and system_round_bug, + "test will fail; failure is probably due to a " + "buggy system round function") + def test_round_large(self): + # Issue #1869: integral floats should remain unchanged + self.assertEqual(round(5e15-1), 5e15-1) + self.assertEqual(round(5e15), 5e15) + self.assertEqual(round(5e15+1), 5e15+1) + self.assertEqual(round(5e15+2), 5e15+2) + self.assertEqual(round(5e15+3), 5e15+3) + def test_setattr(self): setattr(sys, 'spam', 1) self.assertEqual(sys.spam, 1) Modified: sandbox/trunk/newgil/Lib/test/test_signal.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_signal.py (original) +++ sandbox/trunk/newgil/Lib/test/test_signal.py Tue Nov 10 20:16:31 2009 @@ -367,7 +367,9 @@ if signal.getitimer(self.itimer) == (0.0, 0.0): break # sig_vtalrm handler stopped this itimer else: - self.fail('timeout waiting for sig_vtalrm signal') + self.fail('timeout waiting for sig_vtalrm signal; ' + 'signal.getitimer(self.itimer) gives: %s' % + (signal.getitimer(self.itimer),)) # virtual itimer should be (0.0, 0.0) now self.assertEquals(signal.getitimer(self.itimer), (0.0, 0.0)) Modified: sandbox/trunk/newgil/Lib/test/test_threading.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_threading.py (original) +++ sandbox/trunk/newgil/Lib/test/test_threading.py Tue Nov 10 20:16:31 2009 @@ -113,6 +113,8 @@ _thread.start_new_thread(f, ()) done.wait() self.assertFalse(ident[0] is None) + # Kill the "immortal" _DummyThread + del threading._active[ident[0]] # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): @@ -141,11 +143,9 @@ def test_foreign_thread(self): # Check that a "foreign" thread can use the threading module. def f(mutex): - # Acquiring an RLock forces an entry for the foreign + # Calling current_thread() forces an entry for the foreign # thread to get made in the threading._active map. - r = threading.RLock() - r.acquire() - r.release() + threading.current_thread() mutex.release() mutex = threading.Lock() @@ -506,8 +506,11 @@ class LockTests(lock_tests.LockTests): locktype = staticmethod(threading.Lock) -class RLockTests(lock_tests.RLockTests): - locktype = staticmethod(threading.RLock) +class PyRLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading._PyRLock) + +class CRLockTests(lock_tests.RLockTests): + locktype = staticmethod(threading._CRLock) class EventTests(lock_tests.EventTests): eventtype = staticmethod(threading.Event) @@ -527,7 +530,7 @@ def test_main(): - test.support.run_unittest(LockTests, RLockTests, EventTests, + test.support.run_unittest(LockTests, PyRLockTests, CRLockTests, EventTests, ConditionAsRLockTests, ConditionTests, SemaphoreTests, BoundedSemaphoreTests, ThreadTests, Modified: sandbox/trunk/newgil/Lib/threading.py ============================================================================== --- sandbox/trunk/newgil/Lib/threading.py (original) +++ sandbox/trunk/newgil/Lib/threading.py Tue Nov 10 20:16:31 2009 @@ -27,6 +27,10 @@ _allocate_lock = _thread.allocate_lock _get_ident = _thread.get_ident ThreadError = _thread.error +try: + _CRLock = _thread.RLock +except AttributeError: + _CRLock = None del _thread @@ -79,8 +83,12 @@ Lock = _allocate_lock -def RLock(*args, **kwargs): - return _RLock(*args, **kwargs) +def RLock(verbose=None, *args, **kwargs): + if verbose is None: + verbose = _VERBOSE + if (__debug__ and verbose) or _CRLock is None: + return _PyRLock(verbose, *args, **kwargs) + return _CRLock(*args, **kwargs) class _RLock(_Verbose): @@ -92,14 +100,16 @@ def __repr__(self): owner = self._owner - return "<%s(%s, %d)>" % ( - self.__class__.__name__, - owner and owner.name, - self._count) + try: + owner = _active[owner].name + except KeyError: + pass + return "<%s owner=%r count=%d>" % ( + self.__class__.__name__, owner, self._count) def acquire(self, blocking=True): - me = current_thread() - if self._owner is me: + me = _get_ident() + if self._owner == me: self._count = self._count + 1 if __debug__: self._note("%s.acquire(%s): recursive success", self, blocking) @@ -118,7 +128,7 @@ __enter__ = acquire def release(self): - if self._owner is not current_thread(): + if self._owner != _get_ident(): raise RuntimeError("cannot release un-acquired lock") self._count = count = self._count - 1 if not count: @@ -152,7 +162,9 @@ return (count, owner) def _is_owned(self): - return self._owner is current_thread() + return self._owner == _get_ident() + +_PyRLock = _RLock def Condition(*args, **kwargs): Modified: sandbox/trunk/newgil/Misc/ACKS ============================================================================== --- sandbox/trunk/newgil/Misc/ACKS (original) +++ sandbox/trunk/newgil/Misc/ACKS Tue Nov 10 20:16:31 2009 @@ -472,6 +472,7 @@ Don MacMillen Steve Majewski Grzegorz Makarewicz +Dave Malcolm Ken Manheimer Vladimir Marangozov David Marek Modified: sandbox/trunk/newgil/Misc/NEWS ============================================================================== --- sandbox/trunk/newgil/Misc/NEWS (original) +++ sandbox/trunk/newgil/Misc/NEWS Tue Nov 10 20:16:31 2009 @@ -123,6 +123,18 @@ Library ------- +- Issue #3001: Add a C implementation of recursive locks which is used by + default when instantiating a `threading.RLock` object. This makes + recursive locks as fast as regular non-recursive locks (previously, + they were slower by 10x to 15x). + +- Issue #7282: Fix a memory leak when an RLock was used in a thread other + than those started through `threading.Thread` (for example, using + `_thread.start_new_thread()`). + +- Issue #7187: Importlib would not silence the IOError raised when trying to + write new bytecode when it was made read-only. + - Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. Modified: sandbox/trunk/newgil/Misc/Vim/vimrc ============================================================================== --- sandbox/trunk/newgil/Misc/Vim/vimrc (original) +++ sandbox/trunk/newgil/Misc/Vim/vimrc Tue Nov 10 20:16:31 2009 @@ -15,35 +15,32 @@ " Only basic settings needed to enforce the style guidelines are set. " Some suggested options are listed but commented out at the end of this file. - -" Number of spaces to use for an indent. -" This will affect Ctrl-T and 'autoindent'. -" Python: 4 spaces -" C: 4 spaces -au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 -au BufRead *.c,*.h set shiftwidth=8 -au BufNewFile *.c,*.h set shiftwidth=4 - " Number of spaces that a pre-existing tab is equal to. " For the amount of space used for a new tab use shiftwidth. -" Python: 8 -" C: 8 au BufRead,BufNewFile *py,*pyw,*.c,*.h set tabstop=8 -" Replace tabs with the equivalent number of spaces. -" Also have an autocmd for Makefiles since they require hard tabs. -" Python: yes -" C: yes -" Makefile: no -au BufRead,BufNewFile *.py,*.pyw,*.c,*.h set expandtab +" What to use for an indent. +" This will affect Ctrl-T and 'autoindent'. +" Python: 4 spaces +" C: tabs (pre-existing files) or 4 spaces (new files) +au BufRead,BufNewFile *.py,*pyw set shiftwidth=4 +au BufRead,BufNewFile *.py,*.pyw set expandtab +fu Select_c_style() + if search('^\t', 'n', 150) + set shiftwidth=8 + set noexpandtab + el + set shiftwidth=4 + set expandtab + en +endf +au BufRead,BufNewFile *.c,*.h call Select_c_style() au BufRead,BufNewFile Makefile* set noexpandtab -" Use the below highlight group when displaying bad whitespace is desired +" Use the below highlight group when displaying bad whitespace is desired. highlight BadWhitespace ctermbg=red guibg=red " Display tabs at the beginning of a line in Python mode as bad. -" Should be done for C code, but not until all code has been moved to 4-space -" indents. au BufRead,BufNewFile *.py,*.pyw match BadWhitespace /^\t\+/ " Make trailing whitespace be flagged as bad. au BufRead,BufNewFile *.py,*.pyw,*.c,*.h match BadWhitespace /\s\+$/ Modified: sandbox/trunk/newgil/Modules/_threadmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/_threadmodule.c (original) +++ sandbox/trunk/newgil/Modules/_threadmodule.c Tue Nov 10 20:16:31 2009 @@ -155,6 +155,273 @@ lock_methods, /*tp_methods*/ }; +/* Recursive lock objects */ + +typedef struct { + PyObject_HEAD + PyThread_type_lock rlock_lock; + long rlock_owner; + unsigned long rlock_count; + PyObject *in_weakreflist; +} rlockobject; + +static void +rlock_dealloc(rlockobject *self) +{ + assert(self->rlock_lock); + if (self->in_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + /* Unlock the lock so it's safe to free it */ + if (self->rlock_count > 0) + PyThread_release_lock(self->rlock_lock); + + PyThread_free_lock(self->rlock_lock); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) +{ + char *kwlist[] = {"blocking", NULL}; + int blocking = 1; + long tid; + int r = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:acquire", kwlist, + &blocking)) + return NULL; + + tid = PyThread_get_thread_ident(); + if (self->rlock_count > 0 && tid == self->rlock_owner) { + unsigned long count = self->rlock_count + 1; + if (count <= self->rlock_count) { + PyErr_SetString(PyExc_OverflowError, + "Internal lock count overflowed"); + return NULL; + } + self->rlock_count = count; + Py_RETURN_TRUE; + } + + if (self->rlock_count > 0 || + !PyThread_acquire_lock(self->rlock_lock, 0)) { + if (!blocking) { + Py_RETURN_FALSE; + } + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock(self->rlock_lock, blocking); + Py_END_ALLOW_THREADS + } + if (r) { + assert(self->rlock_count == 0); + self->rlock_owner = tid; + self->rlock_count = 1; + } + + return PyBool_FromLong(r); +} + +PyDoc_STRVAR(rlock_acquire_doc, +"acquire(blocking=True) -> bool\n\ +\n\ +Lock the lock. `blocking` indicates whether we should wait\n\ +for the lock to be available or not. If `blocking` is False\n\ +and another thread holds the lock, the method will return False\n\ +immediately. If `blocking` is True and another thread holds\n\ +the lock, the method will wait for the lock to be released,\n\ +take it and then return True.\n\ +(note: the blocking operation is not interruptible.)\n\ +\n\ +In all other cases, the method will return True immediately.\n\ +Precisely, if the current thread already holds the lock, its\n\ +internal counter is simply incremented. If nobody holds the lock,\n\ +the lock is taken and its internal counter initialized to 1."); + +static PyObject * +rlock_release(rlockobject *self) +{ + long tid = PyThread_get_thread_ident(); + + if (self->rlock_count == 0 || self->rlock_owner != tid) { + PyErr_SetString(PyExc_RuntimeError, + "cannot release un-acquired lock"); + return NULL; + } + if (--self->rlock_count == 0) { + self->rlock_owner = 0; + PyThread_release_lock(self->rlock_lock); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(rlock_release_doc, +"release()\n\ +\n\ +Release the lock, allowing another thread that is blocked waiting for\n\ +the lock to acquire the lock. The lock must be in the locked state,\n\ +and must be locked by the same thread that unlocks it; otherwise a\n\ +`RuntimeError` is raised.\n\ +\n\ +Do note that if the lock was acquire()d several times in a row by the\n\ +current thread, release() needs to be called as many times for the lock\n\ +to be available for other threads."); + +static PyObject * +rlock_acquire_restore(rlockobject *self, PyObject *arg) +{ + long owner; + unsigned long count; + int r = 1; + + if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner)) + return NULL; + + if (!PyThread_acquire_lock(self->rlock_lock, 0)) { + Py_BEGIN_ALLOW_THREADS + r = PyThread_acquire_lock(self->rlock_lock, 1); + Py_END_ALLOW_THREADS + } + if (!r) { + PyErr_SetString(ThreadError, "couldn't acquire lock"); + return NULL; + } + assert(self->rlock_count == 0); + self->rlock_owner = owner; + self->rlock_count = count; + Py_RETURN_NONE; +} + +PyDoc_STRVAR(rlock_acquire_restore_doc, +"_acquire_restore(state) -> None\n\ +\n\ +For internal use by `threading.Condition`."); + +static PyObject * +rlock_release_save(rlockobject *self) +{ + long owner; + unsigned long count; + + owner = self->rlock_owner; + count = self->rlock_count; + self->rlock_count = 0; + self->rlock_owner = 0; + PyThread_release_lock(self->rlock_lock); + return Py_BuildValue("kl", count, owner); +} + +PyDoc_STRVAR(rlock_release_save_doc, +"_release_save() -> tuple\n\ +\n\ +For internal use by `threading.Condition`."); + + +static PyObject * +rlock_is_owned(rlockobject *self) +{ + long tid = PyThread_get_thread_ident(); + + if (self->rlock_count > 0 && self->rlock_owner == tid) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + +PyDoc_STRVAR(rlock_is_owned_doc, +"_is_owned() -> bool\n\ +\n\ +For internal use by `threading.Condition`."); + +static PyObject * +rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + rlockobject *self; + + self = (rlockobject *) type->tp_alloc(type, 0); + if (self != NULL) { + self->rlock_lock = PyThread_allocate_lock(); + if (self->rlock_lock == NULL) { + type->tp_free(self); + PyErr_SetString(ThreadError, "can't allocate lock"); + return NULL; + } + self->in_weakreflist = NULL; + self->rlock_owner = 0; + self->rlock_count = 0; + } + + return (PyObject *) self; +} + +static PyObject * +rlock_repr(rlockobject *self) +{ + return PyUnicode_FromFormat("<%s owner=%ld count=%lu>", + Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count); +} + + +static PyMethodDef rlock_methods[] = { + {"acquire", (PyCFunction)rlock_acquire, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"release", (PyCFunction)rlock_release, + METH_NOARGS, rlock_release_doc}, + {"_is_owned", (PyCFunction)rlock_is_owned, + METH_NOARGS, rlock_is_owned_doc}, + {"_acquire_restore", (PyCFunction)rlock_acquire_restore, + METH_O, rlock_acquire_restore_doc}, + {"_release_save", (PyCFunction)rlock_release_save, + METH_NOARGS, rlock_release_save_doc}, + {"__enter__", (PyCFunction)rlock_acquire, + METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc}, + {"__exit__", (PyCFunction)rlock_release, + METH_VARARGS, rlock_release_doc}, + {NULL, NULL} /* sentinel */ +}; + + +static PyTypeObject RLocktype = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "_thread.RLock", /*tp_name*/ + sizeof(rlockobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)rlock_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + (reprfunc)rlock_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + rlock_methods, /*tp_methods*/ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + rlock_new /* tp_new */ +}; + static lockobject * newlockobject(void) { @@ -752,6 +1019,8 @@ return NULL; if (PyType_Ready(&Locktype) < 0) return NULL; + if (PyType_Ready(&RLocktype) < 0) + return NULL; /* Create the module and add the functions */ m = PyModule_Create(&threadmodule); @@ -766,6 +1035,10 @@ Py_INCREF(&Locktype); PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype); + Py_INCREF(&RLocktype); + if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0) + return NULL; + Py_INCREF(&localtype); if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) return NULL; Modified: sandbox/trunk/newgil/Tools/scripts/db2pickle.py ============================================================================== --- sandbox/trunk/newgil/Tools/scripts/db2pickle.py (original) +++ sandbox/trunk/newgil/Tools/scripts/db2pickle.py Tue Nov 10 20:16:31 2009 @@ -33,12 +33,12 @@ except ImportError: gdbm = None try: - import dbm as anydbm + import dbm.ndbm as anydbm except ImportError: anydbm = None import sys try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle Modified: sandbox/trunk/newgil/Tools/scripts/pickle2db.py ============================================================================== --- sandbox/trunk/newgil/Tools/scripts/pickle2db.py (original) +++ sandbox/trunk/newgil/Tools/scripts/pickle2db.py Tue Nov 10 20:16:31 2009 @@ -38,12 +38,12 @@ except ImportError: gdbm = None try: - import dbm as anydbm + import dbm.ndbm as anydbm except ImportError: anydbm = None import sys try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle Modified: sandbox/trunk/newgil/Tools/scripts/redemo.py ============================================================================== --- sandbox/trunk/newgil/Tools/scripts/redemo.py (original) +++ sandbox/trunk/newgil/Tools/scripts/redemo.py Tue Nov 10 20:16:31 2009 @@ -1,6 +1,6 @@ """Basic regular expression demostration facility (Perl style syntax).""" -from Tkinter import * +from tkinter import * import re class ReDemo: Modified: sandbox/trunk/newgil/Tools/scripts/win_add2path.py ============================================================================== --- sandbox/trunk/newgil/Tools/scripts/win_add2path.py (original) +++ sandbox/trunk/newgil/Tools/scripts/win_add2path.py Tue Nov 10 20:16:31 2009 @@ -45,13 +45,13 @@ def main(): paths, envpath = modify() if len(paths) > 1: - print "Path(s) added:" - print '\n'.join(paths[1:]) + print("Path(s) added:") + print('\n'.join(paths[1:])) else: - print "No path was added" - print "\nPATH is now:\n%s\n" % envpath - print "Expanded:" - print winreg.ExpandEnvironmentStrings(envpath) + print("No path was added") + print("\nPATH is now:\n%s\n" % envpath) + print("Expanded:") + print(winreg.ExpandEnvironmentStrings(envpath)) if __name__ == '__main__': main() From python-checkins at python.org Tue Nov 10 20:23:36 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 19:23:36 -0000 Subject: [Python-checkins] r76192 - sandbox/trunk/newgil/Python/ceval_gil.h Message-ID: Author: antoine.pitrou Date: Tue Nov 10 20:23:36 2009 New Revision: 76192 Log: A bit more documentation Modified: sandbox/trunk/newgil/Python/ceval_gil.h Modified: sandbox/trunk/newgil/Python/ceval_gil.h ============================================================================== --- sandbox/trunk/newgil/Python/ceval_gil.h (original) +++ sandbox/trunk/newgil/Python/ceval_gil.h Tue Nov 10 20:23:36 2009 @@ -20,32 +20,43 @@ /* Notes about the implementation: - + - The GIL is just a boolean variable (gil_locked) whose access is protected - by a mutex, and whose changes are signalled by a condition variable. The - mutex itself is rarely taken and, therefore, mostly uncontended. + by a mutex (gil_mutex), and whose changes are signalled by a condition + variable (gil_cond). gil_mutex is taken for short periods of time, + and therefore mostly uncontended. - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be able to release the GIL on demand by another thread. A volatile boolean variable (gil_drop_request) is used for that purpose, which is checked - at every turn of the eval loop. + at every turn of the eval loop. That variable is set after a wait of + `interval` microseconds on `gil_cond` has timed out. [Actually, another volatile boolean variable (eval_breaker) is used - which aggregates several conditions into one. Volatile booleans are - ok as signalling means since Python is run on cache-coherent - architectures only.] - - - A thread wanting to take the GIL will first wait for a given amount of - time before setting gil_drop_request. This amount of time defines the - ideal thread switching period. It is available for the user to read - and modify using `sys.{get,set}switchinterval()`. - - - Forced thread switching when releasing the GIL is implemented. When - a thread releases the GIL and gil_drop_request is set, that thread - ensures that another GIL-awaiting thread gets scheduled. It does so - by waiting on a variable (gil_last_holder) controlled through another - {mutex, condition} pair. - + which ORs several conditions into one. Volatile booleans are + sufficient as inter-thread signalling means since Python is run + on cache-coherent architectures only.] + + - A thread wanting to take the GIL will first let pass a given amount of + time (`interval` microseconds) before setting gil_drop_request. This + encourages a defined switching period, but doesn't enforce it since + opcodes can take an arbitrary time to execute. + + The `interval` value is available for the user to read and modify + using the Python API `sys.{get,set}switchinterval()`. + + - When a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. + It does so by waiting on a condition variable (switch_cond) until + the value of gil_last_holder is changed to something else than its + own thread state pointer, indicating that another thread was able to + take the GIL. + + This is meant to prohibit the latency-adverse behaviour on multi-core + machines where one thread would speculatively release the GIL, but still + run and end up being the first to re-acquire it, making the "timeslices" + much longer than expected. + (Note: this mechanism is enabled with FORCE_SWITCHING above) */ #ifndef _POSIX_THREADS @@ -187,21 +198,24 @@ #endif /* _POSIX_THREADS, NT_THREADS */ -/* Whether the GIL is already taken (-1 if uninitialized) */ +/* Whether the GIL is already taken (-1 if uninitialized). This is volatile + because it can be read without any lock taken in ceval.c. */ static volatile int gil_locked = -1; -/* Number of GIL switches since the beginning */ +/* Number of GIL switches since the beginning. */ static unsigned long gil_switch_number = 0; -/* Last thread holding / having held the GIL */ +/* Last thread holding / having held the GIL. This helps us know whether + anyone else was scheduled after we dropped the GIL. */ static PyThreadState *gil_last_holder = NULL; -/* This condition variable allows to put threads to sleep. - In addition, the mutex also protects the above variables. */ +/* This condition variable allows one or several threads to wait until + the GIL is released. In addition, the mutex also protects the above + variables. */ static COND_T gil_cond; static MUTEX_T gil_mutex; #ifdef FORCE_SWITCHING -/* This condition variable forces the GIL-releasing thread to wait for - the scheduling of a GIL-awaiting thread, if any. */ +/* This condition variable helps the GIL-releasing thread wait for + a GIL-awaiting thread to be scheduled and take the GIL. */ static COND_T switch_cond; static MUTEX_T switch_mutex; #endif From python-checkins at python.org Tue Nov 10 20:34:21 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 19:34:21 -0000 Subject: [Python-checkins] r76193 - sandbox/trunk/newgil/Python/sysmodule.c Message-ID: Author: antoine.pitrou Date: Tue Nov 10 20:34:20 2009 New Revision: 76193 Log: Since sys.{get,set}checkinterval() are now no-ops, deprecate them. Modified: sandbox/trunk/newgil/Python/sysmodule.c Modified: sandbox/trunk/newgil/Python/sysmodule.c ============================================================================== --- sandbox/trunk/newgil/Python/sysmodule.c (original) +++ sandbox/trunk/newgil/Python/sysmodule.c Tue Nov 10 20:34:20 2009 @@ -454,6 +454,11 @@ static PyObject * sys_setcheckinterval(PyObject *self, PyObject *args) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.getcheckinterval() and sys.setcheckinterval() " + "are deprecated. Use sys.setswitchinterval() " + "instead.", 1) < 0) + return NULL; if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_check_interval)) return NULL; Py_INCREF(Py_None); @@ -470,6 +475,11 @@ static PyObject * sys_getcheckinterval(PyObject *self, PyObject *args) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.getcheckinterval() and sys.setcheckinterval() " + "are deprecated. Use sys.getswitchinterval() " + "instead.", 1) < 0) + return NULL; return PyLong_FromLong(_check_interval); } From python-checkins at python.org Tue Nov 10 20:35:56 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2009 19:35:56 -0000 Subject: [Python-checkins] r76194 - python/trunk/Doc/library/collections.rst Message-ID: Author: raymond.hettinger Date: Tue Nov 10 20:35:55 2009 New Revision: 76194 Log: Show example of how to make a sorted dictionary Modified: python/trunk/Doc/library/collections.rst Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Tue Nov 10 20:35:55 2009 @@ -884,3 +884,25 @@ `Equivalent OrderedDict recipe `_ that runs on Python 2.4 or later. + +Since an ordered dictionary remembers its insertion order, it can be used +in conjuction with sorting to make a sorted dictionary:: + + >>> # regular unsorted dictionary + >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} + + >>> # dictionary sorted by key + >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) + OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) + + >>> # dictionary sorted by value + >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) + OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) + + >>> # dictionary sorted by length of the key string + >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) + OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)]) + +The new sorted dictionaries maintain their sort order when entries +are deleted. But when new keys are added, the keys are appended +to the end and the sort is not maintained. From python-checkins at python.org Tue Nov 10 20:50:41 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 19:50:41 -0000 Subject: [Python-checkins] r76195 - in python/branches/py3k: Include/ceval.h Include/pystate.h Include/sysmodule.h Lib/test/test_sys.py Makefile.pre.in Objects/longobject.c Python/ceval.c Python/ceval_gil.h Python/pystate.c Python/sysmodule.c Message-ID: Author: antoine.pitrou Date: Tue Nov 10 20:50:40 2009 New Revision: 76195 Log: Merge in the new GIL. Added: python/branches/py3k/Python/ceval_gil.h (contents, props changed) Modified: python/branches/py3k/Include/ceval.h python/branches/py3k/Include/pystate.h python/branches/py3k/Include/sysmodule.h python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Makefile.pre.in python/branches/py3k/Objects/longobject.c python/branches/py3k/Python/ceval.c python/branches/py3k/Python/pystate.c python/branches/py3k/Python/sysmodule.c Modified: python/branches/py3k/Include/ceval.h ============================================================================== --- python/branches/py3k/Include/ceval.h (original) +++ python/branches/py3k/Include/ceval.h Tue Nov 10 20:50:40 2009 @@ -112,10 +112,6 @@ PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); -/* this used to be handled on a per-thread basis - now just two globals */ -PyAPI_DATA(volatile int) _Py_Ticker; -PyAPI_DATA(int) _Py_CheckInterval; - /* Interface for threads. A module that plans to do a blocking system call (or something else @@ -174,6 +170,9 @@ PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReInitThreads(void); +PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); +PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); + #define Py_BEGIN_ALLOW_THREADS { \ PyThreadState *_save; \ _save = PyEval_SaveThread(); @@ -192,6 +191,7 @@ #endif /* !WITH_THREAD */ PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); +PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void); #ifdef __cplusplus Modified: python/branches/py3k/Include/pystate.h ============================================================================== --- python/branches/py3k/Include/pystate.h (original) +++ python/branches/py3k/Include/pystate.h Tue Nov 10 20:50:40 2009 @@ -88,6 +88,8 @@ PyObject *dict; /* Stores per-thread state */ + /* XXX doesn't mean anything anymore (the comment below is obsolete) + => deprecate or remove? */ /* tick_counter is incremented whenever the check_interval ticker * reaches zero. The purpose is to give a useful measure of the number * of interpreted bytecode instructions in a given thread. This Modified: python/branches/py3k/Include/sysmodule.h ============================================================================== --- python/branches/py3k/Include/sysmodule.h (original) +++ python/branches/py3k/Include/sysmodule.h Tue Nov 10 20:50:40 2009 @@ -18,7 +18,6 @@ Py_GCC_ATTRIBUTE((format(printf, 1, 2))); PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc; -PyAPI_DATA(int) _PySys_CheckInterval; PyAPI_FUNC(void) PySys_ResetWarnOptions(void); PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *); Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Tue Nov 10 20:50:40 2009 @@ -154,6 +154,21 @@ sys.setcheckinterval(n) self.assertEquals(sys.getcheckinterval(), n) + def test_switchinterval(self): + self.assertRaises(TypeError, sys.setswitchinterval) + self.assertRaises(TypeError, sys.setswitchinterval, "a") + self.assertRaises(ValueError, sys.setswitchinterval, -1.0) + self.assertRaises(ValueError, sys.setswitchinterval, 0.0) + orig = sys.getswitchinterval() + # sanity check + self.assertTrue(orig < 0.5, orig) + try: + for n in 0.00001, 0.05, 3.0, orig: + sys.setswitchinterval(n) + self.assertAlmostEquals(sys.getswitchinterval(), n) + finally: + sys.setswitchinterval(orig) + def test_recursionlimit(self): self.assertRaises(TypeError, sys.getrecursionlimit, 42) oldlimit = sys.getrecursionlimit() Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Tue Nov 10 20:50:40 2009 @@ -596,7 +596,7 @@ $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) $(OPCODETARGETGEN) $(OPCODETARGETS_H) -Python/ceval.o: $(OPCODETARGETS_H) +Python/ceval.o: $(OPCODETARGETS_H) Python/ceval_gil.h Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \ $(BYTESTR_DEPS) \ Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Tue Nov 10 20:50:40 2009 @@ -96,10 +96,7 @@ #define MIN(x, y) ((x) > (y) ? (y) : (x)) #define SIGCHECK(PyTryBlock) \ - if (--_Py_Ticker < 0) { \ - _Py_Ticker = _Py_CheckInterval; \ - if (PyErr_CheckSignals()) PyTryBlock \ - } + if (PyErr_CheckSignals()) PyTryBlock \ /* forward declaration */ static int bits_in_digit(digit d); Modified: python/branches/py3k/Python/ceval.c ============================================================================== --- python/branches/py3k/Python/ceval.c (original) +++ python/branches/py3k/Python/ceval.c Tue Nov 10 20:50:40 2009 @@ -216,6 +216,28 @@ #endif +#define COMPUTE_EVAL_BREAKER() \ + (eval_breaker = gil_drop_request | pendingcalls_to_do | pending_async_exc) + +#define SET_GIL_DROP_REQUEST() \ + do { gil_drop_request = 1; eval_breaker = 1; } while (0) + +#define RESET_GIL_DROP_REQUEST() \ + do { gil_drop_request = 0; COMPUTE_EVAL_BREAKER(); } while (0) + +#define SIGNAL_PENDING_CALLS() \ + do { pendingcalls_to_do = 1; eval_breaker = 1; } while (0) + +#define UNSIGNAL_PENDING_CALLS() \ + do { pendingcalls_to_do = 0; COMPUTE_EVAL_BREAKER(); } while (0) + +#define SIGNAL_ASYNC_EXC() \ + do { pending_async_exc = 1; eval_breaker = 1; } while (0) + +#define UNSIGNAL_ASYNC_EXC() \ + do { pending_async_exc = 0; COMPUTE_EVAL_BREAKER(); } while (0) + + #ifdef WITH_THREAD #ifdef HAVE_ERRNO_H @@ -223,36 +245,55 @@ #endif #include "pythread.h" -static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */ static PyThread_type_lock pending_lock = 0; /* for pending calls */ static long main_thread = 0; +/* This single variable consolidates all requests to break out of the fast path + in the eval loop. */ +static volatile int eval_breaker = 0; +/* Request for droppping the GIL */ +static volatile int gil_drop_request = 0; +/* Request for running pending calls */ +static volatile int pendingcalls_to_do = 0; +/* Request for looking at the `async_exc` field of the current thread state */ +static volatile int pending_async_exc = 0; + +#include "ceval_gil.h" int PyEval_ThreadsInitialized(void) { - return interpreter_lock != 0; + return gil_created(); } void PyEval_InitThreads(void) { - if (interpreter_lock) + if (gil_created()) return; - interpreter_lock = PyThread_allocate_lock(); - PyThread_acquire_lock(interpreter_lock, 1); + create_gil(); + take_gil(PyThreadState_GET()); main_thread = PyThread_get_thread_ident(); + if (!pending_lock) + pending_lock = PyThread_allocate_lock(); } void PyEval_AcquireLock(void) { - PyThread_acquire_lock(interpreter_lock, 1); + PyThreadState *tstate = PyThreadState_GET(); + if (tstate == NULL) + Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); + take_gil(tstate); } void PyEval_ReleaseLock(void) { - PyThread_release_lock(interpreter_lock); + /* This function must succeed when the current thread state is NULL. + We therefore avoid PyThreadState_GET() which dumps a fatal error + in debug mode. + */ + drop_gil(_PyThreadState_Current); } void @@ -261,8 +302,8 @@ if (tstate == NULL) Py_FatalError("PyEval_AcquireThread: NULL new thread state"); /* Check someone has called PyEval_InitThreads() to create the lock */ - assert(interpreter_lock); - PyThread_acquire_lock(interpreter_lock, 1); + assert(gil_created()); + take_gil(tstate); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError( "PyEval_AcquireThread: non-NULL old thread state"); @@ -275,7 +316,7 @@ Py_FatalError("PyEval_ReleaseThread: NULL thread state"); if (PyThreadState_Swap(NULL) != tstate) Py_FatalError("PyEval_ReleaseThread: wrong thread state"); - PyThread_release_lock(interpreter_lock); + drop_gil(tstate); } /* This function is called from PyOS_AfterFork to ensure that newly @@ -287,17 +328,17 @@ PyEval_ReInitThreads(void) { PyObject *threading, *result; - PyThreadState *tstate; + PyThreadState *tstate = PyThreadState_GET(); - if (!interpreter_lock) + if (!gil_created()) return; /*XXX Can't use PyThread_free_lock here because it does too much error-checking. Doing this cleanly would require adding a new function to each thread_*.h. Instead, just create a new lock and waste a little bit of memory */ - interpreter_lock = PyThread_allocate_lock(); + recreate_gil(); pending_lock = PyThread_allocate_lock(); - PyThread_acquire_lock(interpreter_lock, 1); + take_gil(tstate); main_thread = PyThread_get_thread_ident(); /* Update the threading module with the new state. @@ -317,7 +358,21 @@ Py_DECREF(result); Py_DECREF(threading); } -#endif + +#else +static int eval_breaker = 0; +static int gil_drop_request = 0; +static int pending_async_exc = 0; +#endif /* WITH_THREAD */ + +/* This function is used to signal that async exceptions are waiting to be + raised, therefore it is also useful in non-threaded builds. */ + +void +_PyEval_SignalAsyncExc(void) +{ + SIGNAL_ASYNC_EXC(); +} /* Functions save_thread and restore_thread are always defined so dynamically loaded modules needn't be compiled separately for use @@ -330,8 +385,8 @@ if (tstate == NULL) Py_FatalError("PyEval_SaveThread: NULL tstate"); #ifdef WITH_THREAD - if (interpreter_lock) - PyThread_release_lock(interpreter_lock); + if (gil_created()) + drop_gil(tstate); #endif return tstate; } @@ -342,9 +397,9 @@ if (tstate == NULL) Py_FatalError("PyEval_RestoreThread: NULL tstate"); #ifdef WITH_THREAD - if (interpreter_lock) { + if (gil_created()) { int err = errno; - PyThread_acquire_lock(interpreter_lock, 1); + take_gil(tstate); errno = err; } #endif @@ -390,7 +445,6 @@ } pendingcalls[NPENDINGCALLS]; static int pendingfirst = 0; static int pendinglast = 0; -static volatile int pendingcalls_to_do = 1; /* trigger initialization of lock */ static char pendingbusy = 0; int @@ -429,8 +483,7 @@ pendinglast = j; } /* signal main loop */ - _Py_Ticker = 0; - pendingcalls_to_do = 1; + SIGNAL_PENDING_CALLS(); if (lock != NULL) PyThread_release_lock(lock); return result; @@ -472,7 +525,10 @@ arg = pendingcalls[j].arg; pendingfirst = (j + 1) % NPENDINGCALLS; } - pendingcalls_to_do = pendingfirst != pendinglast; + if (pendingfirst != pendinglast) + SIGNAL_PENDING_CALLS(); + else + UNSIGNAL_PENDING_CALLS(); PyThread_release_lock(pending_lock); /* having released the lock, perform the callback */ if (func == NULL) @@ -538,8 +594,7 @@ pendingcalls[i].arg = arg; pendinglast = j; - _Py_Ticker = 0; - pendingcalls_to_do = 1; /* Signal main loop */ + SIGNAL_PENDING_CALLS(); busy = 0; /* XXX End critical section */ return 0; @@ -552,7 +607,7 @@ if (busy) return 0; busy = 1; - pendingcalls_to_do = 0; + UNSIGNAL_PENDING_CALLS(); for (;;) { int i; int (*func)(void *); @@ -565,7 +620,7 @@ pendingfirst = (i + 1) % NPENDINGCALLS; if (func(arg) < 0) { busy = 0; - pendingcalls_to_do = 1; /* We're not done yet */ + SIGNAL_PENDING_CALLS(); /* We're not done yet */ return -1; } } @@ -658,10 +713,7 @@ fast_next_opcode*/ static int _Py_TracingPossible = 0; -/* for manipulating the thread switch and periodic "stuff" - used to be - per thread, now just a pair o' globals */ -int _Py_CheckInterval = 100; -volatile int _Py_Ticker = 0; /* so that we hit a "tick" first thing */ + PyObject * PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) @@ -791,10 +843,7 @@ #define DISPATCH() \ { \ - /* Avoid multiple loads from _Py_Ticker despite `volatile` */ \ - int _tick = _Py_Ticker - 1; \ - _Py_Ticker = _tick; \ - if (_tick >= 0) { \ + if (!eval_breaker) { \ FAST_DISPATCH(); \ } \ continue; \ @@ -1168,13 +1217,12 @@ async I/O handler); see Py_AddPendingCall() and Py_MakePendingCalls() above. */ - if (--_Py_Ticker < 0) { + if (eval_breaker) { if (*next_instr == SETUP_FINALLY) { /* Make the last opcode before a try: finally: block uninterruptable. */ goto fast_next_opcode; } - _Py_Ticker = _Py_CheckInterval; tstate->tick_counter++; #ifdef WITH_TSC ticked = 1; @@ -1184,39 +1232,31 @@ why = WHY_EXCEPTION; goto on_error; } - if (pendingcalls_to_do) - /* MakePendingCalls() didn't succeed. - Force early re-execution of this - "periodic" code, possibly after - a thread switch */ - _Py_Ticker = 0; } + if (gil_drop_request) { #ifdef WITH_THREAD - if (interpreter_lock) { /* Give another thread a chance */ - if (PyThreadState_Swap(NULL) != tstate) Py_FatalError("ceval: tstate mix-up"); - PyThread_release_lock(interpreter_lock); - + drop_gil(tstate); + /* Other threads may run now */ - - PyThread_acquire_lock(interpreter_lock, 1); + + take_gil(tstate); if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate"); - - /* Check for thread interrupts */ - - if (tstate->async_exc != NULL) { - x = tstate->async_exc; - tstate->async_exc = NULL; - PyErr_SetNone(x); - Py_DECREF(x); - why = WHY_EXCEPTION; - goto on_error; - } - } #endif + } + /* Check for asynchronous exceptions. */ + if (tstate->async_exc != NULL) { + x = tstate->async_exc; + tstate->async_exc = NULL; + UNSIGNAL_ASYNC_EXC(); + PyErr_SetNone(x); + Py_DECREF(x); + why = WHY_EXCEPTION; + goto on_error; + } } fast_next_opcode: Added: python/branches/py3k/Python/ceval_gil.h ============================================================================== --- (empty file) +++ python/branches/py3k/Python/ceval_gil.h Tue Nov 10 20:50:40 2009 @@ -0,0 +1,335 @@ +/* + * Implementation of the Global Interpreter Lock (GIL). + */ + +#include +#include + + +/* First some general settings */ + +/* microseconds (the Python API uses seconds, though) */ +#define DEFAULT_INTERVAL 5000 +static unsigned long gil_interval = DEFAULT_INTERVAL; +#define INTERVAL (gil_interval >= 1 ? gil_interval : 1) + +/* Enable if you want to force the switching of threads at least every `gil_interval` */ +#undef FORCE_SWITCHING +#define FORCE_SWITCHING + + +/* + Notes about the implementation: + + - The GIL is just a boolean variable (gil_locked) whose access is protected + by a mutex (gil_mutex), and whose changes are signalled by a condition + variable (gil_cond). gil_mutex is taken for short periods of time, + and therefore mostly uncontended. + + - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be + able to release the GIL on demand by another thread. A volatile boolean + variable (gil_drop_request) is used for that purpose, which is checked + at every turn of the eval loop. That variable is set after a wait of + `interval` microseconds on `gil_cond` has timed out. + + [Actually, another volatile boolean variable (eval_breaker) is used + which ORs several conditions into one. Volatile booleans are + sufficient as inter-thread signalling means since Python is run + on cache-coherent architectures only.] + + - A thread wanting to take the GIL will first let pass a given amount of + time (`interval` microseconds) before setting gil_drop_request. This + encourages a defined switching period, but doesn't enforce it since + opcodes can take an arbitrary time to execute. + + The `interval` value is available for the user to read and modify + using the Python API `sys.{get,set}switchinterval()`. + + - When a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. + It does so by waiting on a condition variable (switch_cond) until + the value of gil_last_holder is changed to something else than its + own thread state pointer, indicating that another thread was able to + take the GIL. + + This is meant to prohibit the latency-adverse behaviour on multi-core + machines where one thread would speculatively release the GIL, but still + run and end up being the first to re-acquire it, making the "timeslices" + much longer than expected. + (Note: this mechanism is enabled with FORCE_SWITCHING above) +*/ + +#ifndef _POSIX_THREADS +/* This means pthreads are not implemented in libc headers, hence the macro + not present in unistd.h. But they still can be implemented as an external + library (e.g. gnu pth in pthread emulation) */ +# ifdef HAVE_PTHREAD_H +# include /* _POSIX_THREADS */ +# endif +#endif + + +#ifdef _POSIX_THREADS + +/* + * POSIX support + */ + +#include + +#define ADD_MICROSECONDS(tv, interval) \ +do { \ + tv.tv_usec += (long) interval; \ + tv.tv_sec += tv.tv_usec / 1000000; \ + tv.tv_usec %= 1000000; \ +} while (0) + +/* We assume all modern POSIX systems have gettimeofday() */ +#ifdef GETTIMEOFDAY_NO_TZ +#define GETTIMEOFDAY(ptv) gettimeofday(ptv) +#else +#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL) +#endif + +#define MUTEX_T pthread_mutex_t +#define MUTEX_INIT(mut) \ + if (pthread_mutex_init(&mut, NULL)) { \ + Py_FatalError("pthread_mutex_init(" #mut ") failed"); }; +#define MUTEX_LOCK(mut) \ + if (pthread_mutex_lock(&mut)) { \ + Py_FatalError("pthread_mutex_lock(" #mut ") failed"); }; +#define MUTEX_UNLOCK(mut) \ + if (pthread_mutex_unlock(&mut)) { \ + Py_FatalError("pthread_mutex_unlock(" #mut ") failed"); }; + +#define COND_T pthread_cond_t +#define COND_INIT(cond) \ + if (pthread_cond_init(&cond, NULL)) { \ + Py_FatalError("pthread_cond_init(" #cond ") failed"); }; +#define COND_PREPARE(cond) +#define COND_SIGNAL(cond) \ + if (pthread_cond_signal(&cond)) { \ + Py_FatalError("pthread_cond_signal(" #cond ") failed"); }; +#define COND_WAIT(cond, mut) \ + if (pthread_cond_wait(&cond, &mut)) { \ + Py_FatalError("pthread_cond_wait(" #cond ") failed"); }; +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ + { \ + int r; \ + struct timespec ts; \ + struct timeval deadline; \ + \ + GETTIMEOFDAY(&deadline); \ + ADD_MICROSECONDS(deadline, microseconds); \ + ts.tv_sec = deadline.tv_sec; \ + ts.tv_nsec = deadline.tv_usec * 1000; \ + \ + r = pthread_cond_timedwait(&cond, &mut, &ts); \ + if (r == ETIMEDOUT) \ + timeout_result = 1; \ + else if (r) \ + Py_FatalError("pthread_cond_timedwait(" #cond ") failed"); \ + else \ + timeout_result = 0; \ + } \ + +#elif defined(NT_THREADS) + +/* + * Windows (2000 and later, as well as (hopefully) CE) support + */ + +#include + +#define MUTEX_T HANDLE +#define MUTEX_INIT(mut) \ + if (!(mut = CreateMutex(NULL, FALSE, NULL))) { \ + Py_FatalError("CreateMutex(" #mut ") failed"); }; +#define MUTEX_LOCK(mut) \ + if (WaitForSingleObject(mut, INFINITE) != WAIT_OBJECT_0) { \ + Py_FatalError("WaitForSingleObject(" #mut ") failed"); }; +#define MUTEX_UNLOCK(mut) \ + if (!ReleaseMutex(mut)) { \ + Py_FatalError("ReleaseMutex(" #mut ") failed"); }; + +/* We emulate condition variables with events. It is sufficient here. + (WaitForMultipleObjects() allows the event to be caught and the mutex + to be taken atomically) */ +#define COND_T HANDLE +#define COND_INIT(cond) \ + /* auto-reset, non-signalled */ \ + if (!(cond = CreateEvent(NULL, FALSE, FALSE, NULL))) { \ + Py_FatalError("CreateMutex(" #cond ") failed"); }; +#define COND_PREPARE(cond) \ + if (!ResetEvent(cond)) { \ + Py_FatalError("ResetEvent(" #cond ") failed"); }; +#define COND_SIGNAL(cond) \ + if (!SetEvent(cond)) { \ + Py_FatalError("SetEvent(" #cond ") failed"); }; +#define COND_WAIT(cond, mut) \ + { \ + DWORD r; \ + HANDLE objects[2] = { cond, mut }; \ + MUTEX_UNLOCK(mut); \ + r = WaitForMultipleObjects(2, objects, TRUE, INFINITE); \ + if (r != WAIT_OBJECT_0) \ + Py_FatalError("WaitForSingleObject(" #cond ") failed"); \ + } +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ + { \ + DWORD r; \ + HANDLE objects[2] = { cond, mut }; \ + MUTEX_UNLOCK(mut); \ + r = WaitForMultipleObjects(2, objects, TRUE, microseconds / 1000); \ + if (r == WAIT_TIMEOUT) { \ + MUTEX_LOCK(mut); \ + timeout_result = 1; \ + } \ + else if (r != WAIT_OBJECT_0) \ + Py_FatalError("WaitForSingleObject(" #cond ") failed"); \ + else \ + timeout_result = 0; \ + } + +#else + +#error You need either a POSIX-compatible or a Windows system! + +#endif /* _POSIX_THREADS, NT_THREADS */ + + +/* Whether the GIL is already taken (-1 if uninitialized). This is volatile + because it can be read without any lock taken in ceval.c. */ +static volatile int gil_locked = -1; +/* Number of GIL switches since the beginning. */ +static unsigned long gil_switch_number = 0; +/* Last thread holding / having held the GIL. This helps us know whether + anyone else was scheduled after we dropped the GIL. */ +static PyThreadState *gil_last_holder = NULL; + +/* This condition variable allows one or several threads to wait until + the GIL is released. In addition, the mutex also protects the above + variables. */ +static COND_T gil_cond; +static MUTEX_T gil_mutex; + +#ifdef FORCE_SWITCHING +/* This condition variable helps the GIL-releasing thread wait for + a GIL-awaiting thread to be scheduled and take the GIL. */ +static COND_T switch_cond; +static MUTEX_T switch_mutex; +#endif + + +static int gil_created(void) +{ + return gil_locked >= 0; +} + +static void create_gil(void) +{ + MUTEX_INIT(gil_mutex); +#ifdef FORCE_SWITCHING + MUTEX_INIT(switch_mutex); +#endif + COND_INIT(gil_cond); +#ifdef FORCE_SWITCHING + COND_INIT(switch_cond); +#endif + gil_locked = 0; + gil_last_holder = NULL; +} + +static void recreate_gil(void) +{ + create_gil(); +} + +static void drop_gil(PyThreadState *tstate) +{ + /* NOTE: tstate is allowed to be NULL. */ + if (!gil_locked) + Py_FatalError("drop_gil: GIL is not locked"); + if (tstate != NULL && tstate != gil_last_holder) + Py_FatalError("drop_gil: wrong thread state"); + + MUTEX_LOCK(gil_mutex); + gil_locked = 0; + COND_SIGNAL(gil_cond); +#ifdef FORCE_SWITCHING + COND_PREPARE(switch_cond); +#endif + MUTEX_UNLOCK(gil_mutex); + +#ifdef FORCE_SWITCHING + if (gil_drop_request) { + MUTEX_LOCK(switch_mutex); + /* Not switched yet => wait */ + if (gil_last_holder == tstate) + COND_WAIT(switch_cond, switch_mutex); + MUTEX_UNLOCK(switch_mutex); + } +#endif +} + +static void take_gil(PyThreadState *tstate) +{ + int err; + if (tstate == NULL) + Py_FatalError("take_gil: NULL tstate"); + + err = errno; + MUTEX_LOCK(gil_mutex); + + if (!gil_locked) + goto _ready; + + COND_PREPARE(gil_cond); + while (gil_locked) { + int timed_out = 0; + unsigned long saved_switchnum; + + saved_switchnum = gil_switch_number; + COND_TIMED_WAIT(gil_cond, gil_mutex, INTERVAL, timed_out); + /* If we timed out and no switch occurred in the meantime, it is time + to ask the GIL-holding thread to drop it. */ + if (timed_out && gil_locked && gil_switch_number == saved_switchnum) { + SET_GIL_DROP_REQUEST(); + } + } +_ready: +#ifdef FORCE_SWITCHING + /* This mutex must be taken before modifying gil_last_holder (see drop_gil()). */ + MUTEX_LOCK(switch_mutex); +#endif + /* We now hold the GIL */ + gil_locked = 1; + + if (tstate != gil_last_holder) { + gil_last_holder = tstate; + ++gil_switch_number; + } +#ifdef FORCE_SWITCHING + COND_SIGNAL(switch_cond); + MUTEX_UNLOCK(switch_mutex); +#endif + if (gil_drop_request) { + RESET_GIL_DROP_REQUEST(); + } + if (tstate->async_exc != NULL) { + _PyEval_SignalAsyncExc(); + } + + MUTEX_UNLOCK(gil_mutex); + errno = err; +} + +void _PyEval_SetSwitchInterval(unsigned long microseconds) +{ + gil_interval = microseconds; +} + +unsigned long _PyEval_GetSwitchInterval() +{ + return gil_interval; +} Modified: python/branches/py3k/Python/pystate.c ============================================================================== --- python/branches/py3k/Python/pystate.c (original) +++ python/branches/py3k/Python/pystate.c Tue Nov 10 20:50:40 2009 @@ -434,6 +434,7 @@ p->async_exc = exc; HEAD_UNLOCK(); Py_XDECREF(old_exc); + _PyEval_SignalAsyncExc(); return 1; } } Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Tue Nov 10 20:50:40 2009 @@ -448,10 +448,18 @@ See the profiler chapter in the library manual." ); +/* TODO: deprecate */ +static int _check_interval = 100; + static PyObject * sys_setcheckinterval(PyObject *self, PyObject *args) { - if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval)) + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.getcheckinterval() and sys.setcheckinterval() " + "are deprecated. Use sys.setswitchinterval() " + "instead.", 1) < 0) + return NULL; + if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_check_interval)) return NULL; Py_INCREF(Py_None); return Py_None; @@ -467,13 +475,59 @@ static PyObject * sys_getcheckinterval(PyObject *self, PyObject *args) { - return PyLong_FromLong(_Py_CheckInterval); + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "sys.getcheckinterval() and sys.setcheckinterval() " + "are deprecated. Use sys.getswitchinterval() " + "instead.", 1) < 0) + return NULL; + return PyLong_FromLong(_check_interval); } PyDoc_STRVAR(getcheckinterval_doc, "getcheckinterval() -> current check interval; see setcheckinterval()." ); +#ifdef WITH_THREAD +static PyObject * +sys_setswitchinterval(PyObject *self, PyObject *args) +{ + double d; + if (!PyArg_ParseTuple(args, "d:setswitchinterval", &d)) + return NULL; + if (d <= 0.0) { + PyErr_SetString(PyExc_ValueError, + "switch interval must be strictly positive"); + return NULL; + } + _PyEval_SetSwitchInterval((unsigned long) (1e6 * d)); + Py_INCREF(Py_None); + return Py_None; +} + +PyDoc_STRVAR(setswitchinterval_doc, +"setswitchinterval(n)\n\ +\n\ +Set the ideal thread switching delay inside the Python interpreter\n\ +The actual frequency of switching threads can be lower if the\n\ +interpreter executes long sequences of uninterruptible code\n\ +(this is implementation-specific and workload-dependent).\n\ +\n\ +The parameter must represent the desired switching delay in seconds\n\ +A typical value is 0.005 (5 milliseconds)." +); + +static PyObject * +sys_getswitchinterval(PyObject *self, PyObject *args) +{ + return PyFloat_FromDouble(1e-6 * _PyEval_GetSwitchInterval()); +} + +PyDoc_STRVAR(getswitchinterval_doc, +"getswitchinterval() -> current thread switch interval; see setswitchinterval()." +); + +#endif /* WITH_THREAD */ + #ifdef WITH_TSC static PyObject * sys_settscdump(PyObject *self, PyObject *args) @@ -895,6 +949,12 @@ setcheckinterval_doc}, {"getcheckinterval", sys_getcheckinterval, METH_NOARGS, getcheckinterval_doc}, +#ifdef WITH_THREAD + {"setswitchinterval", sys_setswitchinterval, METH_VARARGS, + setswitchinterval_doc}, + {"getswitchinterval", sys_getswitchinterval, METH_NOARGS, + getswitchinterval_doc}, +#endif #ifdef HAVE_DLOPEN {"setdlopenflags", sys_setdlopenflags, METH_VARARGS, setdlopenflags_doc}, From python-checkins at python.org Tue Nov 10 21:49:30 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 20:49:30 -0000 Subject: [Python-checkins] r76196 - in python/trunk: Lib/test/test_unittest.py Lib/unittest/runner.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Tue Nov 10 21:49:30 2009 New Revision: 76196 Log: Issue #7197: Allow unittest.TextTestRunner objects to be pickled and unpickled. This fixes crashes under Windows when trying to run test_multiprocessing in verbose mode. Additionally, Test_TextTestRunner hadn't been enabled in test_unittest. Modified: python/trunk/Lib/test/test_unittest.py python/trunk/Lib/unittest/runner.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_unittest.py ============================================================================== --- python/trunk/Lib/test/test_unittest.py (original) +++ python/trunk/Lib/test/test_unittest.py Tue Nov 10 21:49:30 2009 @@ -17,6 +17,7 @@ import types from copy import deepcopy from cStringIO import StringIO +import pickle ### Support code ################################################################ @@ -3477,6 +3478,19 @@ expected = ['startTestRun', 'stopTestRun'] self.assertEqual(events, expected) + def test_pickle_unpickle(self): + # Issue #7197: a TextTestRunner should be (un)pickleable. This is + # required by test_multiprocessing under Windows (in verbose mode). + import StringIO + # cStringIO objects are not pickleable, but StringIO objects are. + stream = StringIO.StringIO("foo") + runner = unittest.TextTestRunner(stream) + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(runner, protocol=protocol) + obj = pickle.loads(s) + # StringIO objects never compare equal, a cheap test instead. + self.assertEqual(obj.stream.getvalue(), stream.getvalue()) + class TestDiscovery(TestCase): @@ -3766,7 +3780,7 @@ test_support.run_unittest(Test_TestCase, Test_TestLoader, Test_TestSuite, Test_TestResult, Test_FunctionTestCase, Test_TestSkipping, Test_Assertions, TestLongMessage, - Test_TestProgram, TestCleanUp, TestDiscovery) + Test_TestProgram, TestCleanUp, TestDiscovery, Test_TextTestRunner) if __name__ == "__main__": test_main() Modified: python/trunk/Lib/unittest/runner.py ============================================================================== --- python/trunk/Lib/unittest/runner.py (original) +++ python/trunk/Lib/unittest/runner.py Tue Nov 10 21:49:30 2009 @@ -12,6 +12,8 @@ self.stream = stream def __getattr__(self, attr): + if attr == 'stream': + raise AttributeError(attr) return getattr(self.stream,attr) def writeln(self, arg=None): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Nov 10 21:49:30 2009 @@ -426,6 +426,10 @@ Library ------- +- Issue #7197: Allow unittest.TextTestRunner objects to be pickled and + unpickled. This fixes crashes under Windows when trying to run + test_multiprocessing in verbose mode. + - Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. From python-checkins at python.org Tue Nov 10 22:23:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 10 Nov 2009 21:23:15 -0000 Subject: [Python-checkins] r76197 - python/branches/py3k/Objects/unicodeobject.c Message-ID: Author: benjamin.peterson Date: Tue Nov 10 22:23:15 2009 New Revision: 76197 Log: death to compiler warning Modified: python/branches/py3k/Objects/unicodeobject.c Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Tue Nov 10 22:23:15 2009 @@ -2513,7 +2513,9 @@ *p++ = (char)(0x80 | (ch & 0x3f)); continue; } +#ifndef Py_UNICODE_WIDE encodeUCS4: +#endif /* Encode UCS4 Unicode ordinals */ *p++ = (char)(0xf0 | (ch >> 18)); *p++ = (char)(0x80 | ((ch >> 12) & 0x3f)); From python-checkins at python.org Tue Nov 10 22:34:48 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 21:34:48 -0000 Subject: [Python-checkins] r76198 - in python/branches/py3k: Lib/test/test_unittest.py Lib/unittest/runner.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Tue Nov 10 22:34:48 2009 New Revision: 76198 Log: Merged revisions 76196 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76196 | antoine.pitrou | 2009-11-10 21:49:30 +0100 (mar., 10 nov. 2009) | 8 lines Issue #7197: Allow unittest.TextTestRunner objects to be pickled and unpickled. This fixes crashes under Windows when trying to run test_multiprocessing in verbose mode. Additionally, Test_TextTestRunner hadn't been enabled in test_unittest. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_unittest.py python/branches/py3k/Lib/unittest/runner.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_unittest.py ============================================================================== --- python/branches/py3k/Lib/test/test_unittest.py (original) +++ python/branches/py3k/Lib/test/test_unittest.py Tue Nov 10 22:34:48 2009 @@ -17,6 +17,7 @@ import types from copy import deepcopy import io +import pickle ### Support code ################################################################ @@ -3441,6 +3442,17 @@ expected = ['startTestRun', 'stopTestRun'] self.assertEqual(events, expected) + def test_pickle_unpickle(self): + # Issue #7197: a TextTestRunner should be (un)pickleable. This is + # required by test_multiprocessing under Windows (in verbose mode). + stream = io.StringIO("foo") + runner = unittest.TextTestRunner(stream) + for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(runner, protocol) + obj = pickle.loads(s) + # StringIO objects never compare equal, a cheap test instead. + self.assertEqual(obj.stream.getvalue(), stream.getvalue()) + class TestDiscovery(TestCase): @@ -3729,7 +3741,7 @@ support.run_unittest(Test_TestCase, Test_TestLoader, Test_TestSuite, Test_TestResult, Test_FunctionTestCase, Test_TestSkipping, Test_Assertions, TestLongMessage, - Test_TestProgram, TestCleanUp, TestDiscovery) + Test_TestProgram, TestCleanUp, TestDiscovery, Test_TextTestRunner) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Lib/unittest/runner.py ============================================================================== --- python/branches/py3k/Lib/unittest/runner.py (original) +++ python/branches/py3k/Lib/unittest/runner.py Tue Nov 10 22:34:48 2009 @@ -12,6 +12,8 @@ self.stream = stream def __getattr__(self, attr): + if attr in ('stream', '__getstate__'): + raise AttributeError(attr) return getattr(self.stream,attr) def writeln(self, arg=None): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Nov 10 22:34:48 2009 @@ -123,6 +123,10 @@ Library ------- +- Issue #7197: Allow unittest.TextTestRunner objects to be pickled and + unpickled. This fixes crashes under Windows when trying to run + test_multiprocessing in verbose mode. + - Issue #3001: Add a C implementation of recursive locks which is used by default when instantiating a `threading.RLock` object. This makes recursive locks as fast as regular non-recursive locks (previously, From python-checkins at python.org Tue Nov 10 22:39:25 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 21:39:25 -0000 Subject: [Python-checkins] r76199 - python/trunk/Lib/unittest/runner.py Message-ID: Author: antoine.pitrou Date: Tue Nov 10 22:39:25 2009 New Revision: 76199 Log: Backport micro-fix from the py3k svnmerge Modified: python/trunk/Lib/unittest/runner.py Modified: python/trunk/Lib/unittest/runner.py ============================================================================== --- python/trunk/Lib/unittest/runner.py (original) +++ python/trunk/Lib/unittest/runner.py Tue Nov 10 22:39:25 2009 @@ -12,7 +12,7 @@ self.stream = stream def __getattr__(self, attr): - if attr == 'stream': + if attr in ('stream', '__getstate__'): raise AttributeError(attr) return getattr(self.stream,attr) From python-checkins at python.org Tue Nov 10 22:39:56 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 21:39:56 -0000 Subject: [Python-checkins] r76200 - python/branches/py3k Message-ID: Author: antoine.pitrou Date: Tue Nov 10 22:39:56 2009 New Revision: 76200 Log: Blocked revisions 76199 via svnmerge ........ r76199 | antoine.pitrou | 2009-11-10 22:39:25 +0100 (mar., 10 nov. 2009) | 3 lines Backport micro-fix from the py3k svnmerge ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 10 23:38:53 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 22:38:53 -0000 Subject: [Python-checkins] r76201 - python/branches/py3k/Python/sysmodule.c Message-ID: Author: antoine.pitrou Date: Tue Nov 10 23:38:52 2009 New Revision: 76201 Log: Remove obsolete comment. Modified: python/branches/py3k/Python/sysmodule.c Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Tue Nov 10 23:38:52 2009 @@ -448,7 +448,6 @@ See the profiler chapter in the library manual." ); -/* TODO: deprecate */ static int _check_interval = 100; static PyObject * From python-checkins at python.org Wed Nov 11 00:18:31 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 10 Nov 2009 23:18:31 -0000 Subject: [Python-checkins] r76202 - in python/branches/py3k/Doc: library/sys.rst whatsnew/3.2.rst Message-ID: Author: antoine.pitrou Date: Wed Nov 11 00:18:31 2009 New Revision: 76202 Log: Add a couple of words about the new GIL implementation Modified: python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/whatsnew/3.2.rst Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Wed Nov 11 00:18:31 2009 @@ -282,6 +282,9 @@ Return the interpreter's "check interval"; see :func:`setcheckinterval`. + .. deprecated:: 3.2 + Use :func:`getswitchinterval` instead. + .. function:: getdefaultencoding() @@ -345,6 +348,12 @@ collector. +.. function:: getswitchinterval() + + Return the interpreter's "thread switch interval"; see + :func:`setswitchinterval`. + + .. function:: _getframe([depth]) Return a frame object from the call stack. If optional integer *depth* is @@ -626,6 +635,11 @@ performance for programs using threads. Setting it to a value ``<=`` 0 checks every virtual instruction, maximizing responsiveness as well as overhead. + .. deprecated:: 3.2 + This function doesn't have an effect anymore, as the internal logic + for thread switching and asynchronous tasks has been rewritten. + Use :func:`setswitchinterval` instead. + .. function:: setdefaultencoding(name) @@ -689,6 +703,17 @@ limit can lead to a crash. +.. function:: setswitchinterval(interval) + + Set the interpreter's thread switch interval (in seconds). This floating-point + value determines the ideal duration of the "timeslices" allocated to + concurrently running Python threads. Please note that the actual value + can be higher, especially if long-running internal functions or methods + are used. Also, which thread becomes scheduled at the end of the interval + is the operating system's decision. The interpreter doesn't have its + own scheduler. + + .. function:: settrace(tracefunc) .. index:: Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Wed Nov 11 00:18:31 2009 @@ -85,6 +85,27 @@ (Contributed by Georg Brandl and Mattias Br?ndstr?m; `appspot issue 53094 `_.) +Multi-threading +=============== + +* The mechanism for serializing execution of concurrently running Python + threads (generally known as the GIL or Global Interpreter Lock) has been + rewritten. Among the objectives were more predictable switching intervals + and reduced overhead due to lock contention and the number of ensuing + system calls. The notion of a "check interval" to allow thread switches + has been abandoned and replaced by an absolute duration expressed in + seconds. This parameter is tunable through :func:`sys.setswitchinterval()`. + It currently defaults to 5 milliseconds. + + Additional details about the implementation can be read from a `python-dev + mailing-list message + `_ + (however, "priority requests" as exposed in this message have not been + kept for inclusion). + + (Contributed by Antoine Pitrou) + + Optimizations ============= From python-checkins at python.org Wed Nov 11 02:34:44 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 11 Nov 2009 01:34:44 -0000 Subject: [Python-checkins] r76208 - python/trunk/Lib/CGIHTTPServer.py Message-ID: Author: senthil.kumaran Date: Wed Nov 11 02:34:44 2009 New Revision: 76208 Log: CGIHTTPRequestHandler.run_cgi() to use subprocess for Non Unix platforms. Fix based on Issue1235. Modified: python/trunk/Lib/CGIHTTPServer.py Modified: python/trunk/Lib/CGIHTTPServer.py ============================================================================== --- python/trunk/Lib/CGIHTTPServer.py (original) +++ python/trunk/Lib/CGIHTTPServer.py Wed Nov 11 02:34:44 2009 @@ -253,75 +253,44 @@ self.server.handle_error(self.request, self.client_address) os._exit(127) - elif self.have_popen2 or self.have_popen3: - # Windows -- use popen2 or popen3 to create a subprocess - import shutil - if self.have_popen3: - popenx = os.popen3 - else: - popenx = os.popen2 - cmdline = scriptfile + else: + # Non Unix - use subprocess + import subprocess + cmdline = [scriptfile] if self.is_python(scriptfile): interp = sys.executable if interp.lower().endswith("w.exe"): # On Windows, use python.exe, not pythonw.exe interp = interp[:-5] + interp[-4:] - cmdline = "%s -u %s" % (interp, cmdline) - if '=' not in query and '"' not in query: - cmdline = '%s "%s"' % (cmdline, query) - self.log_message("command: %s", cmdline) + cmdline = [interp, '-u'] + cmdline + if '=' not in query: + cmdline.append(query) + + self.log_message("command: %s", subprocess.list2cmdline(cmdline)) try: nbytes = int(length) except (TypeError, ValueError): nbytes = 0 - files = popenx(cmdline, 'b') - fi = files[0] - fo = files[1] - if self.have_popen3: - fe = files[2] + files = subprocess.Popen(cmdline, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + ) if self.command.lower() == "post" and nbytes > 0: data = self.rfile.read(nbytes) - fi.write(data) + else: + data = None # throw away additional data [see bug #427345] while select.select([self.rfile._sock], [], [], 0)[0]: if not self.rfile._sock.recv(1): break - fi.close() - shutil.copyfileobj(fo, self.wfile) - if self.have_popen3: - errors = fe.read() - fe.close() - if errors: - self.log_error('%s', errors) - sts = fo.close() - if sts: - self.log_error("CGI script exit status %#x", sts) - else: - self.log_message("CGI script exited OK") - - else: - # Other O.S. -- execute script in this process - save_argv = sys.argv - save_stdin = sys.stdin - save_stdout = sys.stdout - save_stderr = sys.stderr - try: - save_cwd = os.getcwd() - try: - sys.argv = [scriptfile] - if '=' not in decoded_query: - sys.argv.append(decoded_query) - sys.stdout = self.wfile - sys.stdin = self.rfile - execfile(scriptfile, {"__name__": "__main__"}) - finally: - sys.argv = save_argv - sys.stdin = save_stdin - sys.stdout = save_stdout - sys.stderr = save_stderr - os.chdir(save_cwd) - except SystemExit, sts: - self.log_error("CGI script exit status %s", str(sts)) + stdout, stderr = p.communicate(data) + self.wfile.write(stdout) + if stderr: + self.log_error('%s', stderr) + status = p.returncode + if status: + self.log_error("CGI script exit status %#x", status) else: self.log_message("CGI script exited OK") From solipsis at pitrou.net Wed Nov 11 04:01:18 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 11 Nov 2009 04:01:18 +0100 (CET) Subject: [Python-checkins] py3k (r76202) reference leaks: sum=18 Message-ID: <20091111030118.71A1B17792@ns6635.ovh.net> py3k results for svn r76202 (hg cset cb9544cf0c09) -------------------------------------------------- test_urllib leaked [8, 4, 6] references, sum=18 From python-checkins at python.org Wed Nov 11 05:07:09 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 11 Nov 2009 04:07:09 -0000 Subject: [Python-checkins] r76209 - in python/branches/release26-maint: Lib/CGIHTTPServer.py Message-ID: Author: senthil.kumaran Date: Wed Nov 11 05:07:09 2009 New Revision: 76209 Log: Merged revisions 76208 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76208 | senthil.kumaran | 2009-11-11 07:04:44 +0530 (Wed, 11 Nov 2009) | 3 lines CGIHTTPRequestHandler.run_cgi() to use subprocess for Non Unix platforms. Fix based on Issue1235. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/CGIHTTPServer.py Modified: python/branches/release26-maint/Lib/CGIHTTPServer.py ============================================================================== --- python/branches/release26-maint/Lib/CGIHTTPServer.py (original) +++ python/branches/release26-maint/Lib/CGIHTTPServer.py Wed Nov 11 05:07:09 2009 @@ -257,75 +257,44 @@ self.server.handle_error(self.request, self.client_address) os._exit(127) - elif self.have_popen2 or self.have_popen3: - # Windows -- use popen2 or popen3 to create a subprocess - import shutil - if self.have_popen3: - popenx = os.popen3 - else: - popenx = os.popen2 - cmdline = scriptfile + else: + # Non Unix - use subprocess + import subprocess + cmdline = [scriptfile] if self.is_python(scriptfile): interp = sys.executable if interp.lower().endswith("w.exe"): # On Windows, use python.exe, not pythonw.exe interp = interp[:-5] + interp[-4:] - cmdline = "%s -u %s" % (interp, cmdline) - if '=' not in query and '"' not in query: - cmdline = '%s "%s"' % (cmdline, query) - self.log_message("command: %s", cmdline) + cmdline = [interp, '-u'] + cmdline + if '=' not in query: + cmdline.append(query) + + self.log_message("command: %s", subprocess.list2cmdline(cmdline)) try: nbytes = int(length) except (TypeError, ValueError): nbytes = 0 - files = popenx(cmdline, 'b') - fi = files[0] - fo = files[1] - if self.have_popen3: - fe = files[2] + files = subprocess.Popen(cmdline, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + ) if self.command.lower() == "post" and nbytes > 0: data = self.rfile.read(nbytes) - fi.write(data) + else: + data = None # throw away additional data [see bug #427345] while select.select([self.rfile._sock], [], [], 0)[0]: if not self.rfile._sock.recv(1): break - fi.close() - shutil.copyfileobj(fo, self.wfile) - if self.have_popen3: - errors = fe.read() - fe.close() - if errors: - self.log_error('%s', errors) - sts = fo.close() - if sts: - self.log_error("CGI script exit status %#x", sts) - else: - self.log_message("CGI script exited OK") - - else: - # Other O.S. -- execute script in this process - save_argv = sys.argv - save_stdin = sys.stdin - save_stdout = sys.stdout - save_stderr = sys.stderr - try: - save_cwd = os.getcwd() - try: - sys.argv = [scriptfile] - if '=' not in decoded_query: - sys.argv.append(decoded_query) - sys.stdout = self.wfile - sys.stdin = self.rfile - execfile(scriptfile, {"__name__": "__main__"}) - finally: - sys.argv = save_argv - sys.stdin = save_stdin - sys.stdout = save_stdout - sys.stderr = save_stderr - os.chdir(save_cwd) - except SystemExit, sts: - self.log_error("CGI script exit status %s", str(sts)) + stdout, stderr = p.communicate(data) + self.wfile.write(stdout) + if stderr: + self.log_error('%s', stderr) + status = p.returncode + if status: + self.log_error("CGI script exit status %#x", status) else: self.log_message("CGI script exited OK") From python-checkins at python.org Wed Nov 11 05:17:53 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 11 Nov 2009 04:17:53 -0000 Subject: [Python-checkins] r76210 - in python/branches/py3k: Lib/http/server.py Message-ID: Author: senthil.kumaran Date: Wed Nov 11 05:17:53 2009 New Revision: 76210 Log: Merged revisions 76208 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76208 | senthil.kumaran | 2009-11-11 07:04:44 +0530 (Wed, 11 Nov 2009) | 3 lines CGIHTTPRequestHandler.run_cgi() to use subprocess for Non Unix platforms. Fix based on Issue1235. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/http/server.py Modified: python/branches/py3k/Lib/http/server.py ============================================================================== --- python/branches/py3k/Lib/http/server.py (original) +++ python/branches/py3k/Lib/http/server.py Wed Nov 11 05:17:53 2009 @@ -1071,16 +1071,16 @@ else: # Non-Unix -- use subprocess import subprocess - cmdline = scriptfile + cmdline = [scriptfile] if self.is_python(scriptfile): interp = sys.executable if interp.lower().endswith("w.exe"): # On Windows, use python.exe, not pythonw.exe interp = interp[:-5] + interp[-4:] - cmdline = "%s -u %s" % (interp, cmdline) - if '=' not in query and '"' not in query: - cmdline = '%s "%s"' % (cmdline, query) - self.log_message("command: %s", cmdline) + cmdline = [interp, '-u'] + cmdline + if '=' not in query: + cmdline.append(query) + self.log_message("command: %s", subprocess.list2cmdline(cmdline)) try: nbytes = int(length) except (TypeError, ValueError): @@ -1088,7 +1088,7 @@ p = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + stderr=subprocess.PIPE ) if self.command.lower() == "post" and nbytes > 0: data = self.rfile.read(nbytes) From python-checkins at python.org Wed Nov 11 05:21:23 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 11 Nov 2009 04:21:23 -0000 Subject: [Python-checkins] r76211 - in python/branches/release31-maint: Lib/http/server.py Message-ID: Author: senthil.kumaran Date: Wed Nov 11 05:21:22 2009 New Revision: 76211 Log: Merged revisions 76210 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76210 | senthil.kumaran | 2009-11-11 09:47:53 +0530 (Wed, 11 Nov 2009) | 10 lines Merged revisions 76208 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76208 | senthil.kumaran | 2009-11-11 07:04:44 +0530 (Wed, 11 Nov 2009) | 3 lines CGIHTTPRequestHandler.run_cgi() to use subprocess for Non Unix platforms. Fix based on Issue1235. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/http/server.py Modified: python/branches/release31-maint/Lib/http/server.py ============================================================================== --- python/branches/release31-maint/Lib/http/server.py (original) +++ python/branches/release31-maint/Lib/http/server.py Wed Nov 11 05:21:22 2009 @@ -1063,16 +1063,16 @@ else: # Non-Unix -- use subprocess import subprocess - cmdline = scriptfile + cmdline = [scriptfile] if self.is_python(scriptfile): interp = sys.executable if interp.lower().endswith("w.exe"): # On Windows, use python.exe, not pythonw.exe interp = interp[:-5] + interp[-4:] - cmdline = "%s -u %s" % (interp, cmdline) - if '=' not in query and '"' not in query: - cmdline = '%s "%s"' % (cmdline, query) - self.log_message("command: %s", cmdline) + cmdline = [interp, '-u'] + cmdline + if '=' not in query: + cmdline.append(query) + self.log_message("command: %s", subprocess.list2cmdline(cmdline)) try: nbytes = int(length) except (TypeError, ValueError): @@ -1080,7 +1080,7 @@ p = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + stderr=subprocess.PIPE ) if self.command.lower() == "post" and nbytes > 0: data = self.rfile.read(nbytes) From g.brandl at gmx.net Wed Nov 11 08:50:35 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Wed, 11 Nov 2009 07:50:35 +0000 Subject: [Python-checkins] r76202 - in python/branches/py3k/Doc: library/sys.rst whatsnew/3.2.rst In-Reply-To: <14777.8873019435$1257895351@news.gmane.org> References: <14777.8873019435$1257895351@news.gmane.org> Message-ID: antoine.pitrou schrieb: > Author: antoine.pitrou > Date: Wed Nov 11 00:18:31 2009 > New Revision: 76202 > > Log: > Add a couple of words about the new GIL implementation > +.. function:: getswitchinterval() > + > + Return the interpreter's "thread switch interval"; see > + :func:`setswitchinterval`. Please add .. versionadded:: tags for this and setswitchinterval(). Georg From python-checkins at python.org Wed Nov 11 18:22:35 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 11 Nov 2009 17:22:35 -0000 Subject: [Python-checkins] r76212 - python/trunk/Lib/CGIHTTPServer.py Message-ID: Author: senthil.kumaran Date: Wed Nov 11 18:22:35 2009 New Revision: 76212 Log: Fixing the NameError on Windows - issue1235 Modified: python/trunk/Lib/CGIHTTPServer.py Modified: python/trunk/Lib/CGIHTTPServer.py ============================================================================== --- python/trunk/Lib/CGIHTTPServer.py (original) +++ python/trunk/Lib/CGIHTTPServer.py Wed Nov 11 18:22:35 2009 @@ -271,11 +271,11 @@ nbytes = int(length) except (TypeError, ValueError): nbytes = 0 - files = subprocess.Popen(cmdline, - stdin = subprocess.PIPE, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE - ) + p = subprocess.Popen(cmdline, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + ) if self.command.lower() == "post" and nbytes > 0: data = self.rfile.read(nbytes) else: From python-checkins at python.org Wed Nov 11 18:24:53 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 11 Nov 2009 17:24:53 -0000 Subject: [Python-checkins] r76213 - in python/branches/release26-maint: Lib/CGIHTTPServer.py Message-ID: Author: senthil.kumaran Date: Wed Nov 11 18:24:53 2009 New Revision: 76213 Log: Merged revisions 76212 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76212 | senthil.kumaran | 2009-11-11 22:52:35 +0530 (Wed, 11 Nov 2009) | 3 lines Fixing the NameError on Windows - issue1235 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/CGIHTTPServer.py Modified: python/branches/release26-maint/Lib/CGIHTTPServer.py ============================================================================== --- python/branches/release26-maint/Lib/CGIHTTPServer.py (original) +++ python/branches/release26-maint/Lib/CGIHTTPServer.py Wed Nov 11 18:24:53 2009 @@ -275,11 +275,11 @@ nbytes = int(length) except (TypeError, ValueError): nbytes = 0 - files = subprocess.Popen(cmdline, - stdin = subprocess.PIPE, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE - ) + p = subprocess.Popen(cmdline, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE + ) if self.command.lower() == "post" and nbytes > 0: data = self.rfile.read(nbytes) else: From python-checkins at python.org Wed Nov 11 19:07:28 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 11 Nov 2009 18:07:28 -0000 Subject: [Python-checkins] r76214 - python/trunk/Lib/bsddb/test/test_replication.py Message-ID: Author: r.david.murray Date: Wed Nov 11 19:07:27 2009 New Revision: 76214 Log: I got the relative magnitudes of the timeout increases reversed, so I'm bumping up the longer test to the 60 seconds I intended to make it. If this doesn't cure the intermittent buildbot timeouts, I'm going to turn that test into a warning rather than a failure. Modified: python/trunk/Lib/bsddb/test/test_replication.py Modified: python/trunk/Lib/bsddb/test/test_replication.py ============================================================================== --- python/trunk/Lib/bsddb/test/test_replication.py (original) +++ python/trunk/Lib/bsddb/test/test_replication.py Wed Nov 11 19:07:27 2009 @@ -116,7 +116,7 @@ # is not generated if the master has no new transactions. # This is solved in BDB 4.6 (#15542). import time - timeout = time.time()+30 + timeout = time.time()+60 while (time.time() Author: r.david.murray Date: Wed Nov 11 19:09:13 2009 New Revision: 76215 Log: Merged revisions 76214 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76214 | r.david.murray | 2009-11-11 13:07:27 -0500 (Wed, 11 Nov 2009) | 5 lines I got the relative magnitudes of the timeout increases reversed, so I'm bumping up the longer test to the 60 seconds I intended to make it. If this doesn't cure the intermittent buildbot timeouts, I'm going to turn that test into a warning rather than a failure. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/bsddb/test/test_replication.py Modified: python/branches/release26-maint/Lib/bsddb/test/test_replication.py ============================================================================== --- python/branches/release26-maint/Lib/bsddb/test/test_replication.py (original) +++ python/branches/release26-maint/Lib/bsddb/test/test_replication.py Wed Nov 11 19:09:13 2009 @@ -116,7 +116,7 @@ # is not generated if the master has no new transactions. # This is solved in BDB 4.6 (#15542). import time - timeout = time.time()+30 + timeout = time.time()+60 while (time.time() Author: antoine.pitrou Date: Wed Nov 11 19:11:36 2009 New Revision: 76216 Log: Our condition variable emulation under Windows is imperfect, which seems to be the cause of the buildbot hangs. Try to fix it, and add some comments. Modified: python/branches/py3k/Python/ceval_gil.h Modified: python/branches/py3k/Python/ceval_gil.h ============================================================================== --- python/branches/py3k/Python/ceval_gil.h (original) +++ python/branches/py3k/Python/ceval_gil.h Wed Nov 11 19:11:36 2009 @@ -153,8 +153,20 @@ Py_FatalError("ReleaseMutex(" #mut ") failed"); }; /* We emulate condition variables with events. It is sufficient here. - (WaitForMultipleObjects() allows the event to be caught and the mutex - to be taken atomically) */ + WaitForMultipleObjects() allows the event to be caught and the mutex + to be taken atomically. + As for SignalObjectAndWait(), its semantics are unfortunately a bit + more foggy. Many sources on the Web define it as atomically releasing + the first object while starting to wait on the second, but MSDN states + it is *not* atomic... + + In any case, the emulation here is tailored for our particular use case. + For example, we don't care how many threads are woken up when a condition + gets signalled. Generic emulations of the pthread_cond_* API using + Win32 functions can be found on the Web. + The following read can be edificating (or not): + http://www.cse.wustl.edu/~schmidt/win32-cv-1.html +*/ #define COND_T HANDLE #define COND_INIT(cond) \ /* auto-reset, non-signalled */ \ @@ -168,12 +180,9 @@ Py_FatalError("SetEvent(" #cond ") failed"); }; #define COND_WAIT(cond, mut) \ { \ - DWORD r; \ - HANDLE objects[2] = { cond, mut }; \ - MUTEX_UNLOCK(mut); \ - r = WaitForMultipleObjects(2, objects, TRUE, INFINITE); \ - if (r != WAIT_OBJECT_0) \ - Py_FatalError("WaitForSingleObject(" #cond ") failed"); \ + if (SignalObjectAndWait(mut, cond, INFINITE, FALSE) != WAIT_OBJECT_0) \ + Py_FatalError("SignalObjectAndWait(" #mut ", " #cond") failed"); \ + MUTEX_LOCK(mut); \ } #define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ { \ @@ -257,7 +266,8 @@ gil_locked = 0; COND_SIGNAL(gil_cond); #ifdef FORCE_SWITCHING - COND_PREPARE(switch_cond); + if (gil_drop_request) + COND_PREPARE(switch_cond); #endif MUTEX_UNLOCK(gil_mutex); @@ -266,6 +276,11 @@ MUTEX_LOCK(switch_mutex); /* Not switched yet => wait */ if (gil_last_holder == tstate) + /* NOTE: if COND_WAIT does not atomically start waiting when + releasing the mutex, another thread can run through, take + the GIL and drop it again, and reset the condition + (COND_PREPARE above) before we even had a chance to wait + for it. */ COND_WAIT(switch_cond, switch_mutex); MUTEX_UNLOCK(switch_mutex); } From python-checkins at python.org Wed Nov 11 21:55:08 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 11 Nov 2009 20:55:08 -0000 Subject: [Python-checkins] r76217 - in python/trunk: Lib/test/test_tarfile.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Wed Nov 11 21:55:07 2009 New Revision: 76217 Log: Issue #7295: Do not use a hardcoded file name in test_tarfile. Modified: python/trunk/Lib/test/test_tarfile.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Wed Nov 11 21:55:07 2009 @@ -27,11 +27,8 @@ def md5sum(data): return md5(data).hexdigest() -def path(path): - return test_support.findfile(path) - -TEMPDIR = os.path.join(tempfile.gettempdir(), "test_tarfile_tmp") -tarname = path("testtar.tar") +TEMPDIR = os.path.abspath(test_support.TESTFN) +tarname = test_support.findfile("testtar.tar") gzipname = os.path.join(TEMPDIR, "testtar.tar.gz") bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2") tmpname = os.path.join(TEMPDIR, "tmp.tar") @@ -1263,8 +1260,7 @@ def test_main(): - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) + os.makedirs(TEMPDIR) tests = [ UstarReadTest, Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 11 21:55:07 2009 @@ -1559,6 +1559,8 @@ Tests ----- +- Issue #7295: Do not use a hardcoded file name in test_tarfile. + - Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. From python-checkins at python.org Wed Nov 11 21:57:55 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 11 Nov 2009 20:57:55 -0000 Subject: [Python-checkins] r76218 - in python/branches/release26-maint: Lib/test/test_tarfile.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Wed Nov 11 21:57:55 2009 New Revision: 76218 Log: Merged revisions 76217 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76217 | antoine.pitrou | 2009-11-11 21:55:07 +0100 (mer., 11 nov. 2009) | 3 lines Issue #7295: Do not use a hardcoded file name in test_tarfile. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_tarfile.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/test/test_tarfile.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_tarfile.py (original) +++ python/branches/release26-maint/Lib/test/test_tarfile.py Wed Nov 11 21:57:55 2009 @@ -27,11 +27,8 @@ def md5sum(data): return md5(data).hexdigest() -def path(path): - return test_support.findfile(path) - -TEMPDIR = os.path.join(tempfile.gettempdir(), "test_tarfile_tmp") -tarname = path("testtar.tar") +TEMPDIR = os.path.abspath(test_support.TESTFN) +tarname = test_support.findfile("testtar.tar") gzipname = os.path.join(TEMPDIR, "testtar.tar.gz") bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2") tmpname = os.path.join(TEMPDIR, "tmp.tar") @@ -1165,8 +1162,7 @@ def test_main(): - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) + os.makedirs(TEMPDIR) tests = [ UstarReadTest, Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Nov 11 21:57:55 2009 @@ -77,6 +77,8 @@ Tests ----- +- Issue #7295: Do not use a hardcoded file name in test_tarfile. + - Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. From python-checkins at python.org Wed Nov 11 21:59:38 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 11 Nov 2009 20:59:38 -0000 Subject: [Python-checkins] r76219 - in python/branches/py3k: Lib/test/test_tarfile.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Wed Nov 11 21:59:38 2009 New Revision: 76219 Log: Merged revisions 76217 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76217 | antoine.pitrou | 2009-11-11 21:55:07 +0100 (mer., 11 nov. 2009) | 3 lines Issue #7295: Do not use a hardcoded file name in test_tarfile. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_tarfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Wed Nov 11 21:59:38 2009 @@ -26,11 +26,8 @@ def md5sum(data): return md5(data).hexdigest() -def path(path): - return support.findfile(path) - -TEMPDIR = os.path.join(tempfile.gettempdir(), "test_tarfile_tmp") -tarname = path("testtar.tar") +TEMPDIR = os.path.abspath(support.TESTFN) +tarname = support.findfile("testtar.tar") gzipname = os.path.join(TEMPDIR, "testtar.tar.gz") bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2") tmpname = os.path.join(TEMPDIR, "tmp.tar") @@ -1244,8 +1241,7 @@ def test_main(): - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) + os.makedirs(TEMPDIR) tests = [ UstarReadTest, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Nov 11 21:59:38 2009 @@ -373,6 +373,8 @@ Tests ----- +- Issue #7295: Do not use a hardcoded file name in test_tarfile. + - Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. From python-checkins at python.org Wed Nov 11 22:01:34 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 11 Nov 2009 21:01:34 -0000 Subject: [Python-checkins] r76220 - in python/branches/release31-maint: Lib/test/test_tarfile.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Wed Nov 11 22:01:33 2009 New Revision: 76220 Log: Merged revisions 76219 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76219 | antoine.pitrou | 2009-11-11 21:59:38 +0100 (mer., 11 nov. 2009) | 9 lines Merged revisions 76217 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76217 | antoine.pitrou | 2009-11-11 21:55:07 +0100 (mer., 11 nov. 2009) | 3 lines Issue #7295: Do not use a hardcoded file name in test_tarfile. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_tarfile.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/test/test_tarfile.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tarfile.py (original) +++ python/branches/release31-maint/Lib/test/test_tarfile.py Wed Nov 11 22:01:33 2009 @@ -26,11 +26,8 @@ def md5sum(data): return md5(data).hexdigest() -def path(path): - return support.findfile(path) - -TEMPDIR = os.path.join(tempfile.gettempdir(), "test_tarfile_tmp") -tarname = path("testtar.tar") +TEMPDIR = os.path.abspath(support.TESTFN) +tarname = support.findfile("testtar.tar") gzipname = os.path.join(TEMPDIR, "testtar.tar.gz") bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2") tmpname = os.path.join(TEMPDIR, "tmp.tar") @@ -1146,8 +1143,7 @@ def test_main(): - if not os.path.exists(TEMPDIR): - os.mkdir(TEMPDIR) + os.makedirs(TEMPDIR) tests = [ UstarReadTest, Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Nov 11 22:01:33 2009 @@ -144,6 +144,8 @@ Tests ----- +- Issue #7295: Do not use a hardcoded file name in test_tarfile. + - Issue #7270: Add some dedicated unit tests for multi-thread synchronization primitives such as Lock, RLock, Condition, Event and Semaphore. From python-checkins at python.org Wed Nov 11 23:03:32 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 11 Nov 2009 22:03:32 -0000 Subject: [Python-checkins] r76221 - python/branches/py3k/Doc/library/sys.rst Message-ID: Author: antoine.pitrou Date: Wed Nov 11 23:03:32 2009 New Revision: 76221 Log: Add version tags to sys.{get,set}switchinterval Modified: python/branches/py3k/Doc/library/sys.rst Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Wed Nov 11 23:03:32 2009 @@ -353,6 +353,8 @@ Return the interpreter's "thread switch interval"; see :func:`setswitchinterval`. + .. versionadded:: 3.2 + .. function:: _getframe([depth]) @@ -713,6 +715,8 @@ is the operating system's decision. The interpreter doesn't have its own scheduler. + .. versionadded:: 3.2 + .. function:: settrace(tracefunc) From solipsis at pitrou.net Thu Nov 12 00:43:20 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 12 Nov 2009 00:43:20 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76221): sum=8 Message-ID: <20091111234320.F2D5C17893@ns6635.ovh.net> py3k results for svn r76221 (hg cset 53f94c394157) -------------------------------------------------- test_urllib leaked [2, 2, 4] references, sum=8 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogcDD7lA', '-x', 'test_httpservers'] From nnorwitz at gmail.com Thu Nov 12 00:48:09 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 11 Nov 2009 18:48:09 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (3) Message-ID: <20091111234809.GA12783@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_distutils leaked [-25, -25, 0] references, sum=-50 test_itertools leaked [32, 0, 0] references, sum=32 test_ssl leaked [0, 0, -420] references, sum=-420 Less important issues: ---------------------- test_cmd_line leaked [25, 0, 0] references, sum=25 From python-checkins at python.org Thu Nov 12 09:29:47 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 12 Nov 2009 08:29:47 -0000 Subject: [Python-checkins] r76223 - python/trunk/Doc/library/profile.rst Message-ID: Author: georg.brandl Date: Thu Nov 12 09:29:46 2009 New Revision: 76223 Log: Give the profile module a module directive. Modified: python/trunk/Doc/library/profile.rst Modified: python/trunk/Doc/library/profile.rst ============================================================================== --- python/trunk/Doc/library/profile.rst (original) +++ python/trunk/Doc/library/profile.rst Thu Nov 12 09:29:46 2009 @@ -7,6 +7,8 @@ .. sectionauthor:: James Roskind +.. module:: profile + :synopsis: Python source profiler. .. index:: single: InfoSeek Corporation From python-checkins at python.org Thu Nov 12 10:10:02 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 12 Nov 2009 09:10:02 -0000 Subject: [Python-checkins] r76224 - python/trunk/Doc/tutorial/stdlib.rst Message-ID: Author: ezio.melotti Date: Thu Nov 12 10:10:02 2009 New Revision: 76224 Log: fix highlight in the datetime example Modified: python/trunk/Doc/tutorial/stdlib.rst Modified: python/trunk/Doc/tutorial/stdlib.rst ============================================================================== --- python/trunk/Doc/tutorial/stdlib.rst (original) +++ python/trunk/Doc/tutorial/stdlib.rst Thu Nov 12 10:10:02 2009 @@ -179,7 +179,7 @@ formatting and manipulation. The module also supports objects that are timezone aware. :: - # dates are easily constructed and formatted + >>> # dates are easily constructed and formatted >>> from datetime import date >>> now = date.today() >>> now @@ -187,7 +187,7 @@ >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.' - # dates support calendar arithmetic + >>> # dates support calendar arithmetic >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days From python-checkins at python.org Thu Nov 12 11:35:53 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 12 Nov 2009 10:35:53 -0000 Subject: [Python-checkins] r76225 - in python/branches/release26-maint: Doc/tutorial/stdlib.rst Message-ID: Author: ezio.melotti Date: Thu Nov 12 11:35:52 2009 New Revision: 76225 Log: fix highlight in the datetime example Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/tutorial/stdlib.rst Modified: python/branches/release26-maint/Doc/tutorial/stdlib.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/stdlib.rst (original) +++ python/branches/release26-maint/Doc/tutorial/stdlib.rst Thu Nov 12 11:35:52 2009 @@ -179,7 +179,7 @@ formatting and manipulation. The module also supports objects that are timezone aware. :: - # dates are easily constructed and formatted + >>> # dates are easily constructed and formatted >>> from datetime import date >>> now = date.today() >>> now @@ -187,7 +187,7 @@ >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.' - # dates support calendar arithmetic + >>> # dates support calendar arithmetic >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days From python-checkins at python.org Thu Nov 12 11:38:56 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 12 Nov 2009 10:38:56 -0000 Subject: [Python-checkins] r76226 - in python/branches/py3k: Doc/tutorial/stdlib.rst Message-ID: Author: ezio.melotti Date: Thu Nov 12 11:38:55 2009 New Revision: 76226 Log: fix highlight in the datetime example Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/tutorial/stdlib.rst Modified: python/branches/py3k/Doc/tutorial/stdlib.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/stdlib.rst (original) +++ python/branches/py3k/Doc/tutorial/stdlib.rst Thu Nov 12 11:38:55 2009 @@ -181,7 +181,7 @@ formatting and manipulation. The module also supports objects that are timezone aware. :: - # dates are easily constructed and formatted + >>> # dates are easily constructed and formatted >>> from datetime import date >>> now = date.today() >>> now @@ -189,7 +189,7 @@ >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.' - # dates support calendar arithmetic + >>> # dates support calendar arithmetic >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days From python-checkins at python.org Thu Nov 12 11:41:24 2009 From: python-checkins at python.org (ezio.melotti) Date: Thu, 12 Nov 2009 10:41:24 -0000 Subject: [Python-checkins] r76227 - in python/branches/release31-maint: Doc/tutorial/stdlib.rst Message-ID: Author: ezio.melotti Date: Thu Nov 12 11:41:24 2009 New Revision: 76227 Log: fix highlight in the datetime example Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/tutorial/stdlib.rst Modified: python/branches/release31-maint/Doc/tutorial/stdlib.rst ============================================================================== --- python/branches/release31-maint/Doc/tutorial/stdlib.rst (original) +++ python/branches/release31-maint/Doc/tutorial/stdlib.rst Thu Nov 12 11:41:24 2009 @@ -181,7 +181,7 @@ formatting and manipulation. The module also supports objects that are timezone aware. :: - # dates are easily constructed and formatted + >>> # dates are easily constructed and formatted >>> from datetime import date >>> now = date.today() >>> now @@ -189,7 +189,7 @@ >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.' - # dates support calendar arithmetic + >>> # dates support calendar arithmetic >>> birthday = date(1964, 7, 31) >>> age = now - birthday >>> age.days From nnorwitz at gmail.com Thu Nov 12 11:57:11 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 12 Nov 2009 05:57:11 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091112105711.GA23341@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [0, -81, 420] references, sum=339 Less important issues: ---------------------- From python-checkins at python.org Thu Nov 12 18:42:47 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 12 Nov 2009 17:42:47 -0000 Subject: [Python-checkins] r76228 - python/branches/release31-maint/Doc/whatsnew/3.1.rst Message-ID: Author: raymond.hettinger Date: Thu Nov 12 18:42:47 2009 New Revision: 76228 Log: Add examples to whatsnew entry for OrderedDict. Modified: python/branches/release31-maint/Doc/whatsnew/3.1.rst Modified: python/branches/release31-maint/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/release31-maint/Doc/whatsnew/3.1.rst (original) +++ python/branches/release31-maint/Doc/whatsnew/3.1.rst Thu Nov 12 18:42:47 2009 @@ -81,6 +81,28 @@ PEP written by Armin Ronacher and Raymond Hettinger. Implementation written by Raymond Hettinger. +Since an ordered dictionary remembers its insertion order, it can be used +in conjuction with sorting to make a sorted dictionary:: + + >>> # regular unsorted dictionary + >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} + + >>> # dictionary sorted by key + >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) + OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) + + >>> # dictionary sorted by value + >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) + OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) + + >>> # dictionary sorted by length of the key string + >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) + OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)]) + +The new sorted dictionaries maintain their sort order when entries +are deleted. But when new keys are added, the keys are appended +to the end and the sort is not maintained. + PEP 378: Format Specifier for Thousands Separator ================================================= From python-checkins at python.org Thu Nov 12 23:56:06 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 12 Nov 2009 22:56:06 -0000 Subject: [Python-checkins] r76229 - python/branches/py3k/Python/ceval_gil.h Message-ID: Author: antoine.pitrou Date: Thu Nov 12 23:56:02 2009 New Revision: 76229 Log: Try to strengthen condition-waiting under Windows. If it doesn't work (doesn't solve erratic freezes) we'll have to resort to tougher (Windows-only) measures. Modified: python/branches/py3k/Python/ceval_gil.h Modified: python/branches/py3k/Python/ceval_gil.h ============================================================================== --- python/branches/py3k/Python/ceval_gil.h (original) +++ python/branches/py3k/Python/ceval_gil.h Thu Nov 12 23:56:02 2009 @@ -106,7 +106,7 @@ #define COND_INIT(cond) \ if (pthread_cond_init(&cond, NULL)) { \ Py_FatalError("pthread_cond_init(" #cond ") failed"); }; -#define COND_PREPARE(cond) +#define COND_RESET(cond) #define COND_SIGNAL(cond) \ if (pthread_cond_signal(&cond)) { \ Py_FatalError("pthread_cond_signal(" #cond ") failed"); }; @@ -172,7 +172,7 @@ /* auto-reset, non-signalled */ \ if (!(cond = CreateEvent(NULL, FALSE, FALSE, NULL))) { \ Py_FatalError("CreateMutex(" #cond ") failed"); }; -#define COND_PREPARE(cond) \ +#define COND_RESET(cond) \ if (!ResetEvent(cond)) { \ Py_FatalError("ResetEvent(" #cond ") failed"); }; #define COND_SIGNAL(cond) \ @@ -265,23 +265,21 @@ MUTEX_LOCK(gil_mutex); gil_locked = 0; COND_SIGNAL(gil_cond); -#ifdef FORCE_SWITCHING - if (gil_drop_request) - COND_PREPARE(switch_cond); -#endif MUTEX_UNLOCK(gil_mutex); #ifdef FORCE_SWITCHING - if (gil_drop_request) { + if (gil_drop_request && tstate != NULL) { MUTEX_LOCK(switch_mutex); /* Not switched yet => wait */ - if (gil_last_holder == tstate) + if (gil_last_holder == tstate) { + RESET_GIL_DROP_REQUEST(); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take the GIL and drop it again, and reset the condition - (COND_PREPARE above) before we even had a chance to wait - for it. */ + before we even had a chance to wait for it. */ COND_WAIT(switch_cond, switch_mutex); + COND_RESET(switch_cond); + } MUTEX_UNLOCK(switch_mutex); } #endif @@ -299,7 +297,7 @@ if (!gil_locked) goto _ready; - COND_PREPARE(gil_cond); + COND_RESET(gil_cond); while (gil_locked) { int timed_out = 0; unsigned long saved_switchnum; From solipsis at pitrou.net Fri Nov 13 00:22:43 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Thu, 12 Nov 2009 23:22:43 +0000 (UTC) Subject: [Python-checkins] =?utf-8?q?r76229_-_python/branches/py3k/Python/?= =?utf-8?q?ceval=5Fgil=2Eh?= References: <907.381208571856$1258066688@news.gmane.org> Message-ID: writes: > > Log: > Try to strengthen condition-waiting under Windows. > If it doesn't work (doesn't solve erratic freezes) we'll have to resort > to tougher (Windows-only) measures. Now I've just noticed that the buildbot whose freeze I was worried about also sometimes freezes on the 3.1 branch (*). So perhaps the new GIL has nothing to do with it. (*) http://www.python.org/dev/buildbot/3.1/builders/x86%20XP-4%203.1/builds/214/steps/test/logs/stdio From python-checkins at python.org Fri Nov 13 00:39:44 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2009 23:39:44 -0000 Subject: [Python-checkins] r76230 - in python/trunk: Doc/library/functions.rst Lib/test/test_codeop.py Lib/test/test_compile.py Lib/test/test_parser.py Misc/NEWS Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h Message-ID: Author: benjamin.peterson Date: Fri Nov 13 00:39:44 2009 New Revision: 76230 Log: fix several compile() issues by translating newlines in the tokenizer Modified: python/trunk/Doc/library/functions.rst python/trunk/Lib/test/test_codeop.py python/trunk/Lib/test/test_compile.py python/trunk/Lib/test/test_parser.py python/trunk/Misc/NEWS python/trunk/Parser/parsetok.c python/trunk/Parser/tokenizer.c python/trunk/Parser/tokenizer.h Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Fri Nov 13 00:39:44 2009 @@ -173,11 +173,10 @@ .. note:: - When compiling a string with multi-line statements, line endings must be - represented by a single newline character (``'\n'``), and the input must - be terminated by at least one newline character. If line endings are - represented by ``'\r\n'``, use :meth:`str.replace` to change them into - ``'\n'``. + When compiling a string with multi-line statements in ``'single'`` or + ``'eval'`` mode, input must be terminated by at least one newline + character. This is to facilitate detection of incomplete and complete + statements in the :mod:`code` module. .. versionchanged:: 2.3 The *flags* and *dont_inherit* arguments were added. @@ -185,6 +184,10 @@ .. versionchanged:: 2.6 Support for compiling AST objects. + .. versionchanged:: 2.7 + Allowed use of Windows and Mac newlines. Also input in ``'exec'`` mode + does not have to end in a newline anymore. + .. function:: complex([real[, imag]]) Modified: python/trunk/Lib/test/test_codeop.py ============================================================================== --- python/trunk/Lib/test/test_codeop.py (original) +++ python/trunk/Lib/test/test_codeop.py Fri Nov 13 00:39:44 2009 @@ -295,10 +295,6 @@ self.assertNotEquals(compile_command("a = 1\n", "abc").co_filename, compile("a = 1\n", "def", 'single').co_filename) - def test_no_universal_newlines(self): - code = compile_command("'\rfoo\r'", symbol='eval') - self.assertEqual(eval(code), '\rfoo\r') - def test_main(): run_unittest(CodeopTests) Modified: python/trunk/Lib/test/test_compile.py ============================================================================== --- python/trunk/Lib/test/test_compile.py (original) +++ python/trunk/Lib/test/test_compile.py Fri Nov 13 00:39:44 2009 @@ -5,6 +5,19 @@ class TestSpecifics(unittest.TestCase): + def test_no_ending_newline(self): + compile("hi", "", "exec") + compile("hi\r", "", "exec") + + def test_empty(self): + compile("", "", "exec") + + def test_other_newlines(self): + compile("\r\n", "", "exec") + compile("\r", "", "exec") + compile("hi\r\nstuff\r\ndef f():\n pass\r", "", "exec") + compile("this_is\rreally_old_mac\rdef f():\n pass", "", "exec") + def test_debug_assignment(self): # catch assignments to __debug__ self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single') Modified: python/trunk/Lib/test/test_parser.py ============================================================================== --- python/trunk/Lib/test/test_parser.py (original) +++ python/trunk/Lib/test/test_parser.py Fri Nov 13 00:39:44 2009 @@ -243,9 +243,9 @@ (14, '+', 2, 13), (2, '1', 2, 15), (4, '', 2, 16), - (6, '', 2, -1), - (4, '', 2, -1), - (0, '', 2, -1)], + (6, '', 3, -1), + (4, '', 3, -1), + (0, '', 3, -1)], terminals) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 13 00:39:44 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Fix several issues with compile(). The input can now contain Windows and Mac + newlines and is no longer required to end in a newline. + - Remove length limitation when constructing a complex number from a unicode string. Modified: python/trunk/Parser/parsetok.c ============================================================================== --- python/trunk/Parser/parsetok.c (original) +++ python/trunk/Parser/parsetok.c Fri Nov 13 00:39:44 2009 @@ -51,7 +51,7 @@ initerr(err_ret, filename); - if ((tok = PyTokenizer_FromString(s)) == NULL) { + if ((tok = PyTokenizer_FromString(s, start == file_input)) == NULL) { err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM; return NULL; } Modified: python/trunk/Parser/tokenizer.c ============================================================================== --- python/trunk/Parser/tokenizer.c (original) +++ python/trunk/Parser/tokenizer.c Fri Nov 13 00:39:44 2009 @@ -105,6 +105,7 @@ tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; tok->done = E_OK; tok->fp = NULL; + tok->input = NULL; tok->tabsize = TABSIZE; tok->indent = 0; tok->indstack[0] = 0; @@ -130,6 +131,17 @@ return tok; } +static char * +new_string(const char *s, Py_ssize_t len) +{ + char* result = (char *)PyMem_MALLOC(len + 1); + if (result != NULL) { + memcpy(result, s, len); + result[len] = '\0'; + } + return result; +} + #ifdef PGEN static char * @@ -144,10 +156,10 @@ return feof(tok->fp); } -static const char * -decode_str(const char *str, struct tok_state *tok) +static char * +decode_str(const char *str, int exec_input, struct tok_state *tok) { - return str; + return new_string(str, strlen(str)); } #else /* PGEN */ @@ -162,16 +174,6 @@ return NULL; /* as if it were EOF */ } -static char * -new_string(const char *s, Py_ssize_t len) -{ - char* result = (char *)PyMem_MALLOC(len + 1); - if (result != NULL) { - memcpy(result, s, len); - result[len] = '\0'; - } - return result; -} static char * get_normal_name(char *s) /* for utf-8 and latin-1 */ @@ -586,17 +588,63 @@ } #endif + +static char * +translate_newlines(const char *s, int exec_input, struct tok_state *tok) { + int skip_next_lf = 0, length = strlen(s), final_length; + char *buf, *current; + char c; + buf = PyMem_MALLOC(length + 2); + if (buf == NULL) { + tok->done = E_NOMEM; + return NULL; + } + for (current = buf; (c = *s++);) { + if (skip_next_lf) { + skip_next_lf = 0; + if (c == '\n') { + c = *s; + s++; + if (!c) + break; + } + } + if (c == '\r') { + skip_next_lf = 1; + c = '\n'; + } + *current = c; + current++; + } + /* If this is exec input, add a newline to the end of the file if + there isn't one already. */ + if (exec_input && *current != '\n') { + *current = '\n'; + current++; + } + *current = '\0'; + final_length = current - buf; + if (final_length < length && final_length) + /* should never fail */ + buf = PyMem_REALLOC(buf, final_length + 1); + return buf; +} + /* Decode a byte string STR for use as the buffer of TOK. Look for encoding declarations inside STR, and record them inside TOK. */ static const char * -decode_str(const char *str, struct tok_state *tok) +decode_str(const char *input, int single, struct tok_state *tok) { PyObject* utf8 = NULL; + const char *str; const char *s; const char *newl[2] = {NULL, NULL}; int lineno = 0; + tok->input = str = translate_newlines(input, single, tok); + if (str == NULL) + return NULL; tok->enc = NULL; tok->str = str; if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok)) @@ -651,12 +699,12 @@ /* Set up tokenizer for string */ struct tok_state * -PyTokenizer_FromString(const char *str) +PyTokenizer_FromString(const char *str, int exec_input) { struct tok_state *tok = tok_new(); if (tok == NULL) return NULL; - str = (char *)decode_str(str, tok); + str = (char *)decode_str(str, exec_input, tok); if (str == NULL) { PyTokenizer_Free(tok); return NULL; @@ -702,6 +750,8 @@ #endif if (tok->fp != NULL && tok->buf != NULL) PyMem_FREE(tok->buf); + if (tok->input) + PyMem_FREE((char *)tok->input); PyMem_FREE(tok); } Modified: python/trunk/Parser/tokenizer.h ============================================================================== --- python/trunk/Parser/tokenizer.h (original) +++ python/trunk/Parser/tokenizer.h Fri Nov 13 00:39:44 2009 @@ -52,9 +52,10 @@ #endif const char* enc; const char* str; + const char* input; /* Tokenizer's newline translated copy of the string. */ }; -extern struct tok_state *PyTokenizer_FromString(const char *); +extern struct tok_state *PyTokenizer_FromString(const char *, int); extern struct tok_state *PyTokenizer_FromFile(FILE *, char *, char *); extern void PyTokenizer_Free(struct tok_state *); extern int PyTokenizer_Get(struct tok_state *, char **, char **); From python-checkins at python.org Fri Nov 13 00:42:23 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2009 23:42:23 -0000 Subject: [Python-checkins] r76231 - python/trunk/Lib/code.py Message-ID: Author: benjamin.peterson Date: Fri Nov 13 00:42:23 2009 New Revision: 76231 Log: this main is much more useful Modified: python/trunk/Lib/code.py Modified: python/trunk/Lib/code.py ============================================================================== --- python/trunk/Lib/code.py (original) +++ python/trunk/Lib/code.py Fri Nov 13 00:42:23 2009 @@ -306,6 +306,5 @@ console.interact(banner) -if __name__ == '__main__': - import pdb - pdb.run("interact()\n") +if __name__ == "__main__": + interact() From solipsis at pitrou.net Fri Nov 13 00:43:28 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 13 Nov 2009 00:43:28 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76226): sum=8 Message-ID: <20091112234328.41B4317758@ns6635.ovh.net> py3k results for svn r76226 (hg cset 24701c37772c) -------------------------------------------------- test_urllib leaked [4, 2, 2] references, sum=8 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogmRUDtw', '-x', 'test_httpservers'] From python-checkins at python.org Fri Nov 13 01:18:00 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 00:18:00 -0000 Subject: [Python-checkins] r76232 - in python/branches/py3k: Doc/library/functions.rst Lib/test/test_codeop.py Lib/test/test_compile.py Lib/test/test_parser.py Lib/test/test_pep263.py Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h Message-ID: Author: benjamin.peterson Date: Fri Nov 13 01:17:59 2009 New Revision: 76232 Log: Merged revisions 76230 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76230 | benjamin.peterson | 2009-11-12 17:39:44 -0600 (Thu, 12 Nov 2009) | 2 lines fix several compile() issues by translating newlines in the tokenizer ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Lib/test/test_codeop.py python/branches/py3k/Lib/test/test_compile.py python/branches/py3k/Lib/test/test_parser.py python/branches/py3k/Lib/test/test_pep263.py python/branches/py3k/Parser/parsetok.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Parser/tokenizer.h Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Fri Nov 13 01:17:59 2009 @@ -176,11 +176,15 @@ .. note:: - When compiling a string with multi-line statements, line endings must be - represented by a single newline character (``'\n'``), and the input must - be terminated by at least one newline character. If line endings are - represented by ``'\r\n'``, use :meth:`str.replace` to change them into - ``'\n'``. + When compiling a string with multi-line statements in ``'single'`` or + ``'eval'`` mode, input must be terminated by at least one newline + character. This is to facilitate detection of incomplete and complete + statements in the :mod:`code` module. + + + .. versionchanged:: 3.2 + Allowed use of Windows and Mac newlines. Also input in ``'exec'`` mode + does not have to end in a newline anymore. .. function:: complex([real[, imag]]) Modified: python/branches/py3k/Lib/test/test_codeop.py ============================================================================== --- python/branches/py3k/Lib/test/test_codeop.py (original) +++ python/branches/py3k/Lib/test/test_codeop.py Fri Nov 13 01:17:59 2009 @@ -295,10 +295,6 @@ self.assertNotEquals(compile_command("a = 1\n", "abc").co_filename, compile("a = 1\n", "def", 'single').co_filename) - def test_no_universal_newlines(self): - code = compile_command("'\rfoo\r'", symbol='eval') - self.assertEqual(eval(code), '\rfoo\r') - def test_main(): run_unittest(CodeopTests) Modified: python/branches/py3k/Lib/test/test_compile.py ============================================================================== --- python/branches/py3k/Lib/test/test_compile.py (original) +++ python/branches/py3k/Lib/test/test_compile.py Fri Nov 13 01:17:59 2009 @@ -5,6 +5,19 @@ class TestSpecifics(unittest.TestCase): + def test_no_ending_newline(self): + compile("hi", "", "exec") + compile("hi\r", "", "exec") + + def test_empty(self): + compile("", "", "exec") + + def test_other_newlines(self): + compile("\r\n", "", "exec") + compile("\r", "", "exec") + compile("hi\r\nstuff\r\ndef f():\n pass\r", "", "exec") + compile("this_is\rreally_old_mac\rdef f():\n pass", "", "exec") + def test_debug_assignment(self): # catch assignments to __debug__ self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single') Modified: python/branches/py3k/Lib/test/test_parser.py ============================================================================== --- python/branches/py3k/Lib/test/test_parser.py (original) +++ python/branches/py3k/Lib/test/test_parser.py Fri Nov 13 01:17:59 2009 @@ -237,9 +237,9 @@ (14, '+', 2, 13), (2, '1', 2, 15), (4, '', 2, 16), - (6, '', 2, -1), - (4, '', 2, -1), - (0, '', 2, -1)], + (6, '', 3, -1), + (4, '', 3, -1), + (0, '', 3, -1)], terminals) def test_extended_unpacking(self): Modified: python/branches/py3k/Lib/test/test_pep263.py ============================================================================== --- python/branches/py3k/Lib/test/test_pep263.py (original) +++ python/branches/py3k/Lib/test/test_pep263.py Fri Nov 13 01:17:59 2009 @@ -26,7 +26,7 @@ try: compile(b"# coding: cp932\nprint '\x94\x4e'", "dummy", "exec") except SyntaxError as v: - self.assertEquals(v.text, "print '\u5e74'") + self.assertEquals(v.text, "print '\u5e74'\n") else: self.fail() Modified: python/branches/py3k/Parser/parsetok.c ============================================================================== --- python/branches/py3k/Parser/parsetok.c (original) +++ python/branches/py3k/Parser/parsetok.c Fri Nov 13 01:17:59 2009 @@ -46,13 +46,14 @@ perrdetail *err_ret, int *flags) { struct tok_state *tok; + int exec_input = start == file_input; initerr(err_ret, filename); if (*flags & PyPARSE_IGNORE_COOKIE) - tok = PyTokenizer_FromUTF8(s); + tok = PyTokenizer_FromUTF8(s, exec_input); else - tok = PyTokenizer_FromString(s); + tok = PyTokenizer_FromString(s, exec_input); if (tok == NULL) { err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM; return NULL; Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Fri Nov 13 01:17:59 2009 @@ -119,6 +119,7 @@ tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; tok->done = E_OK; tok->fp = NULL; + tok->input = NULL; tok->tabsize = TABSIZE; tok->indent = 0; tok->indstack[0] = 0; @@ -145,6 +146,17 @@ return tok; } +static char * +new_string(const char *s, Py_ssize_t len) +{ + char* result = (char *)PyMem_MALLOC(len + 1); + if (result != NULL) { + memcpy(result, s, len); + result[len] = '\0'; + } + return result; +} + #ifdef PGEN static char * @@ -159,10 +171,10 @@ return feof(tok->fp); } -static const char * -decode_str(const char *str, struct tok_state *tok) +static char * +decode_str(const char *str, int exec_input, struct tok_state *tok) { - return str; + return new_string(str, strlen(str)); } #else /* PGEN */ @@ -177,16 +189,6 @@ return NULL; /* as if it were EOF */ } -static char * -new_string(const char *s, Py_ssize_t len) -{ - char* result = (char *)PyMem_MALLOC(len + 1); - if (result != NULL) { - memcpy(result, s, len); - result[len] = '\0'; - } - return result; -} static char * get_normal_name(char *s) /* for utf-8 and latin-1 */ @@ -635,17 +637,63 @@ return utf8; } + +static char * +translate_newlines(const char *s, int exec_input, struct tok_state *tok) { + int skip_next_lf = 0, length = strlen(s), final_length; + char *buf, *current; + char c; + buf = PyMem_MALLOC(length + 2); + if (buf == NULL) { + tok->done = E_NOMEM; + return NULL; + } + for (current = buf; (c = *s++);) { + if (skip_next_lf) { + skip_next_lf = 0; + if (c == '\n') { + c = *s; + s++; + if (!c) + break; + } + } + if (c == '\r') { + skip_next_lf = 1; + c = '\n'; + } + *current = c; + current++; + } + /* If this is exec input, add a newline to the end of the file if + there isn't one already. */ + if (exec_input && *current != '\n') { + *current = '\n'; + current++; + } + *current = '\0'; + final_length = current - buf; + if (final_length < length && final_length) + /* should never fail */ + buf = PyMem_REALLOC(buf, final_length + 1); + return buf; +} + /* Decode a byte string STR for use as the buffer of TOK. Look for encoding declarations inside STR, and record them inside TOK. */ static const char * -decode_str(const char *str, struct tok_state *tok) +decode_str(const char *input, int single, struct tok_state *tok) { PyObject* utf8 = NULL; + const char *str; const char *s; const char *newl[2] = {NULL, NULL}; int lineno = 0; + tok->input = str = translate_newlines(input, single, tok); + if (str == NULL) + return NULL; tok->enc = NULL; tok->str = str; if (!check_bom(buf_getc, buf_ungetc, buf_setreadl, tok)) @@ -696,12 +744,12 @@ /* Set up tokenizer for string */ struct tok_state * -PyTokenizer_FromString(const char *str) +PyTokenizer_FromString(const char *str, int exec_input) { struct tok_state *tok = tok_new(); if (tok == NULL) return NULL; - str = (char *)decode_str(str, tok); + str = (char *)decode_str(str, exec_input, tok); if (str == NULL) { PyTokenizer_Free(tok); return NULL; @@ -713,11 +761,18 @@ } struct tok_state * -PyTokenizer_FromUTF8(const char *str) +PyTokenizer_FromUTF8(const char *str, int exec_input) { struct tok_state *tok = tok_new(); if (tok == NULL) return NULL; +#ifndef PGEN + tok->input = str = translate_newlines(str, exec_input, tok); +#endif + if (str == NULL) { + PyTokenizer_Free(tok); + return NULL; + } tok->decoding_state = STATE_RAW; tok->read_coding_spec = 1; tok->enc = NULL; @@ -734,7 +789,6 @@ return tok; } - /* Set up tokenizer for file */ struct tok_state * @@ -780,6 +834,8 @@ #endif if (tok->fp != NULL && tok->buf != NULL) PyMem_FREE(tok->buf); + if (tok->input) + PyMem_FREE((char *)tok->input); PyMem_FREE(tok); } Modified: python/branches/py3k/Parser/tokenizer.h ============================================================================== --- python/branches/py3k/Parser/tokenizer.h (original) +++ python/branches/py3k/Parser/tokenizer.h Fri Nov 13 01:17:59 2009 @@ -58,10 +58,11 @@ #endif const char* enc; /* Encoding for the current str. */ const char* str; + const char* input; /* Tokenizer's newline translated copy of the string. */ }; -extern struct tok_state *PyTokenizer_FromString(const char *); -extern struct tok_state *PyTokenizer_FromUTF8(const char *); +extern struct tok_state *PyTokenizer_FromString(const char *, int); +extern struct tok_state *PyTokenizer_FromUTF8(const char *, int); extern struct tok_state *PyTokenizer_FromFile(FILE *, char*, char *, char *); extern void PyTokenizer_Free(struct tok_state *); From python-checkins at python.org Fri Nov 13 01:45:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 00:45:32 -0000 Subject: [Python-checkins] r76233 - python/branches/py3k/Lib/importlib/_bootstrap.py Message-ID: Author: benjamin.peterson Date: Fri Nov 13 01:45:32 2009 New Revision: 76233 Log: no need to translate newlines in python code anymore Modified: python/branches/py3k/Lib/importlib/_bootstrap.py Modified: python/branches/py3k/Lib/importlib/_bootstrap.py ============================================================================== --- python/branches/py3k/Lib/importlib/_bootstrap.py (original) +++ python/branches/py3k/Lib/importlib/_bootstrap.py Fri Nov 13 01:45:32 2009 @@ -344,21 +344,6 @@ message = "a source path must exist to load {0}".format(fullname) raise ImportError(message) source = self.get_data(source_path) - # Convert to universal newlines. - line_endings = b'\n' - for index, c in enumerate(source): - if c == ord(b'\n'): - break - elif c == ord(b'\r'): - line_endings = b'\r' - try: - if source[index+1] == ord(b'\n'): - line_endings += b'\n' - except IndexError: - pass - break - if line_endings != b'\n': - source = source.replace(line_endings, b'\n') return compile(source, source_path, 'exec', dont_inherit=True) # Never use in implementing import! Imports code within the method. From python-checkins at python.org Fri Nov 13 01:52:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 00:52:43 -0000 Subject: [Python-checkins] r76234 - python/branches/py3k/Doc/library/importlib.rst Message-ID: Author: benjamin.peterson Date: Fri Nov 13 01:52:43 2009 New Revision: 76234 Log: update to reality Modified: python/branches/py3k/Doc/library/importlib.rst Modified: python/branches/py3k/Doc/library/importlib.rst ============================================================================== --- python/branches/py3k/Doc/library/importlib.rst (original) +++ python/branches/py3k/Doc/library/importlib.rst Fri Nov 13 01:52:43 2009 @@ -252,8 +252,8 @@ A concrete implementation of :meth:`importlib.abc.InspectLoader.get_code` that creates code objects from Python source code, by requesting the source code (using - :meth:`source_path` and :meth:`get_data`), converting it to standard - newlines, and compiling it with the built-in :func:`compile` function. + :meth:`source_path` and :meth:`get_data`) and compiling it with the + built-in :func:`compile` function. .. method:: get_source(fullname) From brett at python.org Fri Nov 13 02:38:06 2009 From: brett at python.org (Brett Cannon) Date: Thu, 12 Nov 2009 17:38:06 -0800 Subject: [Python-checkins] r76233 - python/branches/py3k/Lib/importlib/_bootstrap.py In-Reply-To: <4afcac97.051abc0a.5fd0.ffff9e28SMTPIN_ADDED@mx.google.com> References: <4afcac97.051abc0a.5fd0.ffff9e28SMTPIN_ADDED@mx.google.com> Message-ID: On Thu, Nov 12, 2009 at 16:47, benjamin.peterson wrote: > Author: benjamin.peterson > Date: Fri Nov 13 01:45:32 2009 > New Revision: 76233 > > Log: > no need to translate newlines in python code anymore Sweet! Thanks for this, Benjamin! I always hated having this hack in the code since I knew it was a nasty performance hit. I was planning on trying to solve it at some point. Glad you beat me to it. =) > > Modified: > ? python/branches/py3k/Lib/importlib/_bootstrap.py > > Modified: python/branches/py3k/Lib/importlib/_bootstrap.py > ============================================================================== > --- python/branches/py3k/Lib/importlib/_bootstrap.py ? ?(original) > +++ python/branches/py3k/Lib/importlib/_bootstrap.py ? ?Fri Nov 13 01:45:32 2009 > @@ -344,21 +344,6 @@ > ? ? ? ? ? ? message = "a source path must exist to load {0}".format(fullname) > ? ? ? ? ? ? raise ImportError(message) > ? ? ? ? source = self.get_data(source_path) > - ? ? ? ?# Convert to universal newlines. > - ? ? ? ?line_endings = b'\n' > - ? ? ? ?for index, c in enumerate(source): > - ? ? ? ? ? ?if c == ord(b'\n'): > - ? ? ? ? ? ? ? ?break > - ? ? ? ? ? ?elif c == ord(b'\r'): > - ? ? ? ? ? ? ? ?line_endings = b'\r' > - ? ? ? ? ? ? ? ?try: > - ? ? ? ? ? ? ? ? ? ?if source[index+1] == ord(b'\n'): > - ? ? ? ? ? ? ? ? ? ? ? ?line_endings += b'\n' > - ? ? ? ? ? ? ? ?except IndexError: > - ? ? ? ? ? ? ? ? ? ?pass > - ? ? ? ? ? ? ? ?break > - ? ? ? ?if line_endings != b'\n': > - ? ? ? ? ? ?source = source.replace(line_endings, b'\n') > ? ? ? ? return compile(source, source_path, 'exec', dont_inherit=True) > > ? ? # Never use in implementing import! Imports code within the method. > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Fri Nov 13 03:25:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 02:25:09 -0000 Subject: [Python-checkins] r76235 - in python/branches/py3k: Doc/distutils/apiref.rst Doc/distutils/examples.rst Doc/library/2to3.rst Doc/library/bdb.rst Doc/library/io.rst Doc/library/operator.rst Doc/library/pdb.rst Doc/library/profile.rst Doc/library/pty.rst Doc/library/tarfile.rst Doc/library/turtle.rst Doc/library/weakref.rst Doc/library/zipfile.rst Doc/whatsnew/2.6.rst Lib/distutils/command/check.py Lib/inspect.py Lib/test/regrtest.py Lib/test/test_ast.py Lib/test/test_inspect.py Lib/test/test_module.py Lib/test/test_strptime.py Lib/test/test_threading.py Lib/test/test_tokenize.py Lib/tokenize.py Lib/xml/__init__.py Misc/Porting Modules/_io/stringio.c Modules/mathmodule.c Modules/operator.c Objects/descrobject.c Objects/listobject.c Objects/moduleobject.c Parser/tokenizer.c Message-ID: Author: benjamin.peterson Date: Fri Nov 13 03:25:08 2009 New Revision: 76235 Log: Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75149 | gregory.p.smith | 2009-09-29 16:56:31 -0500 (Tue, 29 Sep 2009) | 3 lines Mention issue6972 in extractall docs about overwriting things outside of the supplied path. ........ r75260 | andrew.kuchling | 2009-10-05 16:24:20 -0500 (Mon, 05 Oct 2009) | 1 line Wording fix ........ r75261 | andrew.kuchling | 2009-10-05 16:24:35 -0500 (Mon, 05 Oct 2009) | 1 line Fix narkup ........ r75262 | andrew.kuchling | 2009-10-05 16:25:03 -0500 (Mon, 05 Oct 2009) | 1 line Document 'skip' parameter to constructor ........ r75263 | andrew.kuchling | 2009-10-05 16:25:35 -0500 (Mon, 05 Oct 2009) | 1 line Note side benefit of socket.create_connection() ........ r75265 | andrew.kuchling | 2009-10-05 17:31:11 -0500 (Mon, 05 Oct 2009) | 1 line Reword sentence ........ r75266 | andrew.kuchling | 2009-10-05 17:32:48 -0500 (Mon, 05 Oct 2009) | 1 line Use standard comma punctuation; reword some sentences in the docs ........ r75267 | andrew.kuchling | 2009-10-05 17:42:56 -0500 (Mon, 05 Oct 2009) | 1 line Backport r73983: Document the thousands separator. ........ r75292 | benjamin.peterson | 2009-10-08 22:11:36 -0500 (Thu, 08 Oct 2009) | 1 line death to old CVS keyword ........ r75300 | benjamin.peterson | 2009-10-09 16:48:14 -0500 (Fri, 09 Oct 2009) | 1 line fix some coding style ........ r75376 | benjamin.peterson | 2009-10-11 20:26:07 -0500 (Sun, 11 Oct 2009) | 1 line platform we don't care about ........ r75405 | neil.schemenauer | 2009-10-14 12:17:14 -0500 (Wed, 14 Oct 2009) | 4 lines Issue #1754094: Improve the stack depth calculation in the compiler. There should be no other effect than a small decrease in memory use. Patch by Christopher Tur Lesniewski-Laas. ........ r75429 | benjamin.peterson | 2009-10-14 20:47:28 -0500 (Wed, 14 Oct 2009) | 1 line pep8ify if blocks ........ r75430 | benjamin.peterson | 2009-10-14 20:49:37 -0500 (Wed, 14 Oct 2009) | 1 line use floor division and add a test that exercises the tabsize codepath ........ r75431 | benjamin.peterson | 2009-10-14 20:56:25 -0500 (Wed, 14 Oct 2009) | 1 line change test to what I intended ........ r75432 | benjamin.peterson | 2009-10-14 22:05:39 -0500 (Wed, 14 Oct 2009) | 1 line some cleanups ........ r75433 | benjamin.peterson | 2009-10-14 22:06:55 -0500 (Wed, 14 Oct 2009) | 1 line make inspect.isabstract() always return a boolean; add a test for it, too #7069 ........ r75437 | benjamin.peterson | 2009-10-15 10:44:46 -0500 (Thu, 15 Oct 2009) | 1 line only clear a module's __dict__ if the module is the only one with a reference to it #7140 ........ r75445 | vinay.sajip | 2009-10-16 09:06:44 -0500 (Fri, 16 Oct 2009) | 1 line Issue #7120: logging: Removed import of multiprocessing which is causing crash in GAE. ........ r75501 | antoine.pitrou | 2009-10-18 13:37:11 -0500 (Sun, 18 Oct 2009) | 3 lines Add a comment about unreachable code, and fix a typo ........ r75551 | benjamin.peterson | 2009-10-19 22:14:10 -0500 (Mon, 19 Oct 2009) | 1 line use property api ........ r75572 | benjamin.peterson | 2009-10-20 16:55:17 -0500 (Tue, 20 Oct 2009) | 1 line clarify buffer arg #7178 ........ r75589 | benjamin.peterson | 2009-10-21 21:26:47 -0500 (Wed, 21 Oct 2009) | 1 line whitespace ........ r75590 | benjamin.peterson | 2009-10-21 21:36:47 -0500 (Wed, 21 Oct 2009) | 1 line rewrite to be nice to other implementations ........ r75591 | benjamin.peterson | 2009-10-21 21:50:38 -0500 (Wed, 21 Oct 2009) | 4 lines rewrite for style, clarify, and comments Also, use the hasattr() like scheme of allowing BaseException exceptions through. ........ r75657 | antoine.pitrou | 2009-10-24 07:41:27 -0500 (Sat, 24 Oct 2009) | 3 lines Fix compilation error in debug mode. ........ r75742 | benjamin.peterson | 2009-10-26 17:51:16 -0500 (Mon, 26 Oct 2009) | 1 line use 'is' instead of id() ........ r75868 | benjamin.peterson | 2009-10-27 15:59:18 -0500 (Tue, 27 Oct 2009) | 1 line test expect base classes ........ r75952 | georg.brandl | 2009-10-29 15:38:32 -0500 (Thu, 29 Oct 2009) | 1 line Use the correct function name in docstring. ........ r75953 | georg.brandl | 2009-10-29 15:39:50 -0500 (Thu, 29 Oct 2009) | 1 line Remove mention of the old -X command line switch. ........ r75954 | georg.brandl | 2009-10-29 15:53:00 -0500 (Thu, 29 Oct 2009) | 1 line Use constants instead of magic integers for test result. Do not re-run with --verbose3 for environment changing tests. ........ r75955 | georg.brandl | 2009-10-29 15:54:03 -0500 (Thu, 29 Oct 2009) | 1 line Use a single style for all the docstrings in the math module. ........ r75956 | georg.brandl | 2009-10-29 16:16:34 -0500 (Thu, 29 Oct 2009) | 1 line I do not think the "railroad" program mentioned is still available. ........ r75957 | georg.brandl | 2009-10-29 16:44:56 -0500 (Thu, 29 Oct 2009) | 1 line Fix constant name. ........ r76057 | benjamin.peterson | 2009-11-02 09:06:45 -0600 (Mon, 02 Nov 2009) | 1 line prevent a rather unlikely segfault ........ r76105 | georg.brandl | 2009-11-04 01:38:12 -0600 (Wed, 04 Nov 2009) | 1 line #7259: show correct equivalent for operator.i* operations in docstring; fix minor issues in operator docs. ........ r76139 | benjamin.peterson | 2009-11-06 19:04:38 -0600 (Fri, 06 Nov 2009) | 1 line spelling ........ r76143 | georg.brandl | 2009-11-07 02:26:07 -0600 (Sat, 07 Nov 2009) | 1 line #7271: fix typo. ........ r76162 | benjamin.peterson | 2009-11-08 22:10:53 -0600 (Sun, 08 Nov 2009) | 1 line discuss how to use -p ........ r76223 | georg.brandl | 2009-11-12 02:29:46 -0600 (Thu, 12 Nov 2009) | 1 line Give the profile module a module directive. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/apiref.rst python/branches/py3k/Doc/distutils/examples.rst python/branches/py3k/Doc/library/2to3.rst python/branches/py3k/Doc/library/bdb.rst python/branches/py3k/Doc/library/io.rst python/branches/py3k/Doc/library/operator.rst python/branches/py3k/Doc/library/pdb.rst python/branches/py3k/Doc/library/profile.rst python/branches/py3k/Doc/library/pty.rst python/branches/py3k/Doc/library/tarfile.rst python/branches/py3k/Doc/library/turtle.rst python/branches/py3k/Doc/library/weakref.rst python/branches/py3k/Doc/library/zipfile.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Lib/distutils/command/check.py python/branches/py3k/Lib/inspect.py python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/test_ast.py python/branches/py3k/Lib/test/test_inspect.py python/branches/py3k/Lib/test/test_module.py python/branches/py3k/Lib/test/test_strptime.py python/branches/py3k/Lib/test/test_threading.py python/branches/py3k/Lib/test/test_tokenize.py python/branches/py3k/Lib/tokenize.py python/branches/py3k/Lib/xml/__init__.py python/branches/py3k/Misc/Porting python/branches/py3k/Modules/_io/stringio.c python/branches/py3k/Modules/mathmodule.c python/branches/py3k/Modules/operator.c python/branches/py3k/Objects/descrobject.c python/branches/py3k/Objects/listobject.c python/branches/py3k/Objects/moduleobject.c python/branches/py3k/Parser/tokenizer.c Modified: python/branches/py3k/Doc/distutils/apiref.rst ============================================================================== --- python/branches/py3k/Doc/distutils/apiref.rst (original) +++ python/branches/py3k/Doc/distutils/apiref.rst Fri Nov 13 03:25:08 2009 @@ -1952,7 +1952,7 @@ The ``check`` command performs some tests on the meta-data of a package. -It makes sure for example that all required meta-data are provided through +For example, it verifies that all required meta-data are provided as the arguments passed to the :func:`setup` function. .. % todo Modified: python/branches/py3k/Doc/distutils/examples.rst ============================================================================== --- python/branches/py3k/Doc/distutils/examples.rst (original) +++ python/branches/py3k/Doc/distutils/examples.rst Fri Nov 13 03:25:08 2009 @@ -236,10 +236,10 @@ Checking a package ================== -The ``check`` command allows you to verify if your package meta-data are -meeting the minimum requirements to build a distribution. +The ``check`` command allows you to verify if your package meta-data +meet the minimum requirements to build a distribution. -To run it, just call it over your :file:`setup.py` script. If something is +To run it, just call it using your :file:`setup.py` script. If something is missing, ``check`` will display a warning. Let's take an example with a simple script:: @@ -252,7 +252,7 @@ $ python setup.py check running check - warning: check: missing required meta-data: version ,url + warning: check: missing required meta-data: version, url warning: check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) must be supplied Modified: python/branches/py3k/Doc/library/2to3.rst ============================================================================== --- python/branches/py3k/Doc/library/2to3.rst (original) +++ python/branches/py3k/Doc/library/2to3.rst Fri Nov 13 03:25:08 2009 @@ -86,6 +86,14 @@ The :option:`-v` option enables output of more information on the translation process. +Since some print statements can be parsed as function calls or statements, 2to3 +cannot always read files containing the print function. When 2to3 detects the +presence of the ``from __future__ import print_function`` compiler directive, it +modifies its internal grammar to interpert :func:`print` as a function. This +change can also be enabled manually with the :option:`-p` flag. Use +:option:`-p` to run fixers on code that already has had its print statements +converted. + .. _2to3-fixers: Modified: python/branches/py3k/Doc/library/bdb.rst ============================================================================== --- python/branches/py3k/Doc/library/bdb.rst (original) +++ python/branches/py3k/Doc/library/bdb.rst Fri Nov 13 03:25:08 2009 @@ -62,14 +62,22 @@ * The breakpoint hit count. -.. class:: Bdb() +.. class:: Bdb(skip=None) - The :class:`Bdb` acts as a generic Python debugger base class. + The :class:`Bdb` class acts as a generic Python debugger base class. This class takes care of the details of the trace facility; a derived class should implement user interaction. The standard debugger class (:class:`pdb.Pdb`) is an example. + The *skip* argument, if given, must be an iterable of glob-style + module name patterns. The debugger will not step into frames that + originate in a module that matches one of these patterns. Whether a + frame is considered to originate in a certain module is determined + by the ``__name__`` in the frame globals. + + .. versionadded:: 2.7 + The *skip* argument. The following methods of :class:`Bdb` normally don't need to be overridden. Modified: python/branches/py3k/Doc/library/io.rst ============================================================================== --- python/branches/py3k/Doc/library/io.rst (original) +++ python/branches/py3k/Doc/library/io.rst Fri Nov 13 03:25:08 2009 @@ -98,8 +98,8 @@ *buffering* is an optional integer used to set the buffering policy. By default full buffering is on. Pass 0 to switch buffering off (only allowed - in binary mode), 1 to set line buffering, and an integer > 1 for full - buffering. + in binary mode), 1 to set line buffering, and an integer > 1 to indicate the + size of the buffer. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform Modified: python/branches/py3k/Doc/library/operator.rst ============================================================================== --- python/branches/py3k/Doc/library/operator.rst (original) +++ python/branches/py3k/Doc/library/operator.rst Fri Nov 13 03:25:08 2009 @@ -104,6 +104,14 @@ Return ``a // b``. +.. function:: index(a) + __index__(a) + + Return *a* converted to an integer. Equivalent to ``a.__index__()``. + + .. versionadded:: 2.5 + + .. function:: inv(obj) invert(obj) __inv__(obj) @@ -133,7 +141,7 @@ .. function:: neg(obj) __neg__(obj) - Return *obj* negated. + Return *obj* negated (``-obj``). .. function:: or_(a, b) @@ -145,7 +153,7 @@ .. function:: pos(obj) __pos__(obj) - Return *obj* positive. + Return *obj* positive (``+obj``). .. function:: pow(a, b) @@ -179,13 +187,7 @@ Return the bitwise exclusive or of *a* and *b*. -.. function:: index(a) - __index__(a) - - Return *a* converted to an integer. Equivalent to ``a.__index__()``. - - -Operations which work with sequences include: +Operations which work with sequences (some of them with mappings too) include: .. function:: concat(a, b) __concat__(a, b) @@ -394,67 +396,77 @@ This table shows how abstract operations correspond to operator symbols in the Python syntax and the functions in the :mod:`operator` module. -+-----------------------+-------------------------+---------------------------------+ -| Operation | Syntax | Function | -+=======================+=========================+=================================+ -| Addition | ``a + b`` | ``add(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Concatenation | ``seq1 + seq2`` | ``concat(seq1, seq2)`` | -+-----------------------+-------------------------+---------------------------------+ -| Containment Test | ``obj in seq`` | ``contains(seq, obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a / b`` | ``truediv(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a // b`` | ``floordiv(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise And | ``a & b`` | ``and_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Exclusive Or | ``a ^ b`` | ``xor(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Inversion | ``~ a`` | ``invert(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Or | ``a | b`` | ``or_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Exponentiation | ``a ** b`` | ``pow(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Identity | ``a is b`` | ``is_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Identity | ``a is not b`` | ``is_not(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexed Assignment | ``obj[k] = v`` | ``setitem(obj, k, v)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexed Deletion | ``del obj[k]`` | ``delitem(obj, k)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexing | ``obj[k]`` | ``getitem(obj, k)`` | -+-----------------------+-------------------------+---------------------------------+ -| Left Shift | ``a << b`` | ``lshift(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Modulo | ``a % b`` | ``mod(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Multiplication | ``a * b`` | ``mul(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Negation (Arithmetic) | ``- a`` | ``neg(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Negation (Logical) | ``not a`` | ``not_(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Right Shift | ``a >> b`` | ``rshift(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| String Formatting | ``s % obj`` | ``mod(s, obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Subtraction | ``a - b`` | ``sub(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Truth Test | ``obj`` | ``truth(obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a < b`` | ``lt(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a <= b`` | ``le(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Equality | ``a == b`` | ``eq(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Difference | ``a != b`` | ``ne(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a >= b`` | ``ge(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a > b`` | ``gt(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ ++-----------------------+-------------------------+---------------------------------------+ +| Operation | Syntax | Function | ++=======================+=========================+=======================================+ +| Addition | ``a + b`` | ``add(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Concatenation | ``seq1 + seq2`` | ``concat(seq1, seq2)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Containment Test | ``obj in seq`` | ``contains(seq, obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a / b`` | ``div(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a // b`` | ``floordiv(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise And | ``a & b`` | ``and_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Exclusive Or | ``a ^ b`` | ``xor(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Inversion | ``~ a`` | ``invert(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Or | ``a | b`` | ``or_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Exponentiation | ``a ** b`` | ``pow(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Identity | ``a is b`` | ``is_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Identity | ``a is not b`` | ``is_not(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexed Assignment | ``obj[k] = v`` | ``setitem(obj, k, v)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexed Deletion | ``del obj[k]`` | ``delitem(obj, k)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexing | ``obj[k]`` | ``getitem(obj, k)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Left Shift | ``a << b`` | ``lshift(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Modulo | ``a % b`` | ``mod(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Multiplication | ``a * b`` | ``mul(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Negation (Arithmetic) | ``- a`` | ``neg(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Negation (Logical) | ``not a`` | ``not_(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Positive | ``+ a`` | ``pos(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Right Shift | ``a >> b`` | ``rshift(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Sequence Repetition | ``seq * i`` | ``repeat(seq, i)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slice Assignment | ``seq[i:j] = values`` | ``setitem(seq, slice(i, j), values)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slice Deletion | ``del seq[i:j]`` | ``delitem(seq, slice(i, j))`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slicing | ``seq[i:j]`` | ``getitem(seq, slice(i, j))`` | ++-----------------------+-------------------------+---------------------------------------+ +| String Formatting | ``s % obj`` | ``mod(s, obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Subtraction | ``a - b`` | ``sub(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Truth Test | ``obj`` | ``truth(obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a < b`` | ``lt(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a <= b`` | ``le(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Equality | ``a == b`` | ``eq(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Difference | ``a != b`` | ``ne(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a >= b`` | ``ge(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a > b`` | ``gt(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ Modified: python/branches/py3k/Doc/library/pdb.rst ============================================================================== --- python/branches/py3k/Doc/library/pdb.rst (original) +++ python/branches/py3k/Doc/library/pdb.rst Fri Nov 13 03:25:08 2009 @@ -55,7 +55,7 @@ import pdb; pdb.set_trace() at the location you want to break into the debugger. You can then step through -the code following this statement, and continue running without debugger using +the code following this statement, and continue running without the debugger using the ``c`` command. The typical usage to inspect a crashed program is:: Modified: python/branches/py3k/Doc/library/profile.rst ============================================================================== --- python/branches/py3k/Doc/library/profile.rst (original) +++ python/branches/py3k/Doc/library/profile.rst Fri Nov 13 03:25:08 2009 @@ -6,6 +6,8 @@ .. sectionauthor:: James Roskind +.. module:: profile + :synopsis: Python source profiler. .. index:: single: InfoSeek Corporation Modified: python/branches/py3k/Doc/library/pty.rst ============================================================================== --- python/branches/py3k/Doc/library/pty.rst (original) +++ python/branches/py3k/Doc/library/pty.rst Fri Nov 13 03:25:08 2009 @@ -2,8 +2,8 @@ ======================================== .. module:: pty - :platform: IRIX, Linux - :synopsis: Pseudo-Terminal Handling for SGI and Linux. + :platform: Linux + :synopsis: Pseudo-Terminal Handling for Linux. .. moduleauthor:: Steen Lumholt .. sectionauthor:: Moshe Zadka @@ -13,8 +13,8 @@ controlling terminal programmatically. Because pseudo-terminal handling is highly platform dependent, there is code to -do it only for SGI and Linux. (The Linux code is supposed to work on other -platforms, but hasn't been tested yet.) +do it only for Linux. (The Linux code is supposed to work on other platforms, +but hasn't been tested yet.) The :mod:`pty` module defines the following functions: @@ -31,8 +31,8 @@ .. function:: openpty() Open a new pseudo-terminal pair, using :func:`os.openpty` if possible, or - emulation code for SGI and generic Unix systems. Return a pair of file - descriptors ``(master, slave)``, for the master and the slave end, respectively. + emulation code for generic Unix systems. Return a pair of file descriptors + ``(master, slave)``, for the master and the slave end, respectively. .. function:: spawn(argv[, master_read[, stdin_read]]) Modified: python/branches/py3k/Doc/library/tarfile.rst ============================================================================== --- python/branches/py3k/Doc/library/tarfile.rst (original) +++ python/branches/py3k/Doc/library/tarfile.rst Fri Nov 13 03:25:08 2009 @@ -365,7 +365,7 @@ value. Depending on this value the respective file is either excluded (:const:`True`) or added (:const:`False`). If *filter* is specified it must be a function that takes a :class:`TarInfo` object argument and returns the - changed TarInfo object. If it instead returns :const:`None` the TarInfo + changed :class:`TarInfo` object. If it instead returns :const:`None` the :class:`TarInfo` object will be excluded from the archive. See :ref:`tar-examples` for an example. Modified: python/branches/py3k/Doc/library/turtle.rst ============================================================================== --- python/branches/py3k/Doc/library/turtle.rst (original) +++ python/branches/py3k/Doc/library/turtle.rst Fri Nov 13 03:25:08 2009 @@ -2023,7 +2023,7 @@ Subclass of TurtleScreen, with :ref:`four methods added `. -.. class:: ScrolledCavas(master) +.. class:: ScrolledCanvas(master) :param master: some Tkinter widget to contain the ScrolledCanvas, i.e. a Tkinter-canvas with scrollbars added Modified: python/branches/py3k/Doc/library/weakref.rst ============================================================================== --- python/branches/py3k/Doc/library/weakref.rst (original) +++ python/branches/py3k/Doc/library/weakref.rst Fri Nov 13 03:25:08 2009 @@ -72,10 +72,9 @@ obj = Dict(red=1, green=2, blue=3) # this object is weak referenceable -.. impl-detail:: - - Other built-in types such as :class:`tuple` and :class:`long` do not support - weak references even when subclassed. +Other built-in types such as :class:`tuple` and :class:`long` do not support +weak references even when subclassed (This is an implementation detail and may +be different across various Python implementations.). Extension types can easily be made to support weak references; see :ref:`weakref-support`. Modified: python/branches/py3k/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k/Doc/library/zipfile.rst (original) +++ python/branches/py3k/Doc/library/zipfile.rst Fri Nov 13 03:25:08 2009 @@ -197,6 +197,13 @@ be a subset of the list returned by :meth:`namelist`. *pwd* is the password used for encrypted files. + .. warning:: + + Never extract archives from untrusted sources without prior inspection. + It is possible that files are created outside of *path*, e.g. members + that have absolute filenames starting with ``"/"`` or filenames with two + dots ``".."``. + .. method:: ZipFile.printdir() Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Fri Nov 13 03:25:08 2009 @@ -2416,9 +2416,13 @@ environments. TIPC addresses are 4- or 5-tuples. (Contributed by Alberto Bertogli; :issue:`1646`.) - A new function, :func:`create_connection`, takes an address - and connects to it using an optional timeout value, returning - the connected socket object. + A new function, :func:`create_connection`, takes an address and + connects to it using an optional timeout value, returning the + connected socket object. This function also looks up the address's + type and connects to it using IPv4 or IPv6 as appropriate. Changing + your code to use :func:`create_connection` instead of + ``socket(socket.AF_INET, ...)`` may be all that's required to make + your code work with IPv6. * The base classes in the :mod:`SocketServer` module now support calling a :meth:`handle_timeout` method after a span of inactivity Modified: python/branches/py3k/Lib/distutils/command/check.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/check.py (original) +++ python/branches/py3k/Lib/distutils/command/check.py Fri Nov 13 03:25:08 2009 @@ -92,7 +92,7 @@ missing.append(attr) if missing: - self.warn("missing required meta-data: %s" % ' ,'.join(missing)) + self.warn("missing required meta-data: %s" % ', '.join(missing)) if metadata.author: if not metadata.author_email: self.warn("missing meta-data: if 'author' supplied, " + Modified: python/branches/py3k/Lib/inspect.py ============================================================================== --- python/branches/py3k/Lib/inspect.py (original) +++ python/branches/py3k/Lib/inspect.py Fri Nov 13 03:25:08 2009 @@ -238,7 +238,7 @@ def isabstract(object): """Return true if the object is an abstract base class (ABC).""" - return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT + return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT) def getmembers(object, predicate=None): """Return all members of an object as (name, value) pairs sorted by name. Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Fri Nov 13 03:25:08 2009 @@ -193,6 +193,14 @@ newsoft = min(hard, max(soft, 1024*2048)) resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) +# Test result constants. +PASSED = 1 +FAILED = 0 +ENV_CHANGED = -1 +SKIPPED = -2 +RESOURCE_DENIED = -3 +INTERRUPTED = -4 + from test import support RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', @@ -352,7 +360,7 @@ try: result = runtest(*args, **kwargs) except BaseException as e: - result = -4, e.__class__.__name__ + result = INTERRUPTED, e.__class__.__name__ sys.stdout.flush() print() # Force a newline (just in case) print(json.dumps(result)) @@ -443,19 +451,18 @@ def accumulate_result(test, result): ok, test_time = result test_times.append((test_time, test)) - if ok > 0: + if ok == PASSED: good.append(test) - return 'good' - elif -2 < ok <= 0: + elif ok == FAILED: bad.append(test) - if ok == -1: - environment_changed.append(test) - return 'bad' - else: + elif ok == ENV_CHANGED: + bad.append(test) + environment_changed.append(test) + elif ok == SKIPPED: skipped.append(test) - if ok == -3: - resource_denieds.append(test) - return 'skipped' + elif ok == RESOURCE_DENIED: + skipped.append(test) + resource_denieds.append(test) if use_mp: from threading import Thread @@ -511,7 +518,7 @@ print(stdout) if stderr: print(stderr, file=sys.stderr) - if result[0] == -4: + if result[0] == INTERRUPTED: assert result[1] == 'KeyboardInterrupt' pending.clear() raise KeyboardInterrupt # What else? @@ -532,8 +539,8 @@ try: result = runtest(test, verbose, quiet, testdir, huntrleaks, debug) - which = accumulate_result(test, result) - if verbose3 and which == 'bad': + accumulate_result(test, result) + if verbose3 and result[0] == FAILED: print("Re-running test {} in verbose mode".format(test)) runtest(test, True, quiet, testdir, huntrleaks, debug) except KeyboardInterrupt: @@ -679,15 +686,14 @@ testdir -- test directory huntrleaks -- run multiple times to test for leaks; requires a debug build; a triple corresponding to -R's three arguments - debug -- if true, print tracebacks for failed tests regardless of - verbose setting - Return: - -4 KeyboardInterrupt when run under -j - -3 test skipped because resource denied - -2 test skipped for some other reason - -1 test failed because it changed the execution environment - 0 test failed - 1 test passed + + Returns one of the test result constants: + INTERRUPTED KeyboardInterrupt when run under -j + RESOURCE_DENIED test skipped because resource denied + SKIPPED test skipped for some other reason + ENV_CHANGED test failed because it changed the execution environment + FAILED test failed + PASSED test passed """ support.verbose = verbose # Tell tests to be moderately quiet @@ -843,18 +849,18 @@ if not quiet: print(test, "skipped --", msg) sys.stdout.flush() - return -3, test_time + return RESOURCE_DENIED, test_time except unittest.SkipTest as msg: if not quiet: print(test, "skipped --", msg) sys.stdout.flush() - return -2, test_time + return SKIPPED, test_time except KeyboardInterrupt: raise except support.TestFailed as msg: print("test", test, "failed --", msg) sys.stdout.flush() - return 0, test_time + return FAILED, test_time except: type, value = sys.exc_info()[:2] print("test", test, "crashed --", str(type) + ":", value) @@ -862,13 +868,13 @@ if verbose or debug: traceback.print_exc(file=sys.stdout) sys.stdout.flush() - return 0, test_time + return FAILED, test_time else: if refleak: - return 0, test_time + return FAILED, test_time if environment.changed: - return -1, test_time - return 1, test_time + return ENV_CHANGED, test_time + return PASSED, test_time def cleanup_test_droppings(testname, verbose): import shutil Modified: python/branches/py3k/Lib/test/test_ast.py ============================================================================== --- python/branches/py3k/Lib/test/test_ast.py (original) +++ python/branches/py3k/Lib/test/test_ast.py Fri Nov 13 03:25:08 2009 @@ -154,6 +154,14 @@ im = ast.parse("from . import y").body[0] self.assertIsNone(im.module) + def test_base_classes(self): + self.assertTrue(issubclass(ast.For, ast.stmt)) + self.assertTrue(issubclass(ast.Name, ast.expr)) + self.assertTrue(issubclass(ast.stmt, ast.AST)) + self.assertTrue(issubclass(ast.expr, ast.AST)) + self.assertTrue(issubclass(ast.comprehension, ast.AST)) + self.assertTrue(issubclass(ast.Gt, ast.AST)) + def test_nodeclasses(self): x = ast.BinOp(1, 2, 3, lineno=0) self.assertEquals(x.left, 1) Modified: python/branches/py3k/Lib/test/test_inspect.py ============================================================================== --- python/branches/py3k/Lib/test/test_inspect.py (original) +++ python/branches/py3k/Lib/test/test_inspect.py Fri Nov 13 03:25:08 2009 @@ -120,6 +120,28 @@ self.assertTrue('a' in members) self.assertTrue('b' not in members) + def test_isabstract(self): + from abc import ABCMeta, abstractmethod + + class AbstractClassExample(metaclass=ABCMeta): + + @abstractmethod + def foo(self): + pass + + class ClassExample(AbstractClassExample): + def foo(self): + pass + + a = ClassExample() + + # Test general behaviour. + self.assertTrue(inspect.isabstract(AbstractClassExample)) + self.assertFalse(inspect.isabstract(ClassExample)) + self.assertFalse(inspect.isabstract(a)) + self.assertFalse(inspect.isabstract(int)) + self.assertFalse(inspect.isabstract(5)) + class TestInterpreterStack(IsTestBase): def __init__(self, *args, **kwargs): Modified: python/branches/py3k/Lib/test/test_module.py ============================================================================== --- python/branches/py3k/Lib/test/test_module.py (original) +++ python/branches/py3k/Lib/test/test_module.py Fri Nov 13 03:25:08 2009 @@ -55,6 +55,14 @@ {"__name__": "foo", "__doc__": "foodoc", "bar": 42}) self.assertTrue(foo.__dict__ is d) + def test_dont_clear_dict(self): + # See issue 7140. + def f(): + foo = ModuleType("foo") + foo.bar = 4 + return foo + self.assertEqual(f().__dict__["bar"], 4) + def test_main(): run_unittest(ModuleTests) Modified: python/branches/py3k/Lib/test/test_strptime.py ============================================================================== --- python/branches/py3k/Lib/test/test_strptime.py (original) +++ python/branches/py3k/Lib/test/test_strptime.py Fri Nov 13 03:25:08 2009 @@ -493,9 +493,9 @@ _strptime._strptime_time("10", "%d") _strptime._strptime_time("2005", "%Y") _strptime._TimeRE_cache.locale_time.lang = "Ni" - original_time_re = id(_strptime._TimeRE_cache) + original_time_re = _strptime._TimeRE_cache _strptime._strptime_time("10", "%d") - self.assertNotEqual(original_time_re, id(_strptime._TimeRE_cache)) + self.assertIsNot(original_time_re, _strptime._TimeRE_cache) self.assertEqual(len(_strptime._regex_cache), 1) def test_regex_cleanup(self): @@ -514,11 +514,10 @@ def test_new_localetime(self): # A new LocaleTime instance should be created when a new TimeRE object # is created. - locale_time_id = id(_strptime._TimeRE_cache.locale_time) + locale_time_id = _strptime._TimeRE_cache.locale_time _strptime._TimeRE_cache.locale_time.lang = "Ni" _strptime._strptime_time("10", "%d") - self.assertNotEqual(locale_time_id, - id(_strptime._TimeRE_cache.locale_time)) + self.assertIsNot(locale_time_id, _strptime._TimeRE_cache.locale_time) def test_TimeRE_recreation(self): # The TimeRE instance should be recreated upon changing the locale. @@ -530,15 +529,15 @@ try: _strptime._strptime_time('10', '%d') # Get id of current cache object. - first_time_re_id = id(_strptime._TimeRE_cache) + first_time_re = _strptime._TimeRE_cache try: # Change the locale and force a recreation of the cache. locale.setlocale(locale.LC_TIME, ('de_DE', 'UTF8')) _strptime._strptime_time('10', '%d') # Get the new cache object's id. - second_time_re_id = id(_strptime._TimeRE_cache) + second_time_re = _strptime._TimeRE_cache # They should not be equal. - self.assertNotEqual(first_time_re_id, second_time_re_id) + self.assertIsNot(first_time_re, second_time_re) # Possible test locale is not supported while initial locale is. # If this is the case just suppress the exception and fall-through # to the reseting to the original locale. Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Fri Nov 13 03:25:08 2009 @@ -185,11 +185,13 @@ except AsyncExc: pass else: + # This code is unreachable but it reflects the intent. If we wanted + # to be smarter the above loop wouldn't be infinite. self.fail("AsyncExc not raised") try: self.assertEqual(result, 1) # one thread state modified except UnboundLocalError: - # The exception was raised to quickly for us to get the result. + # The exception was raised too quickly for us to get the result. pass # `worker_started` is set by the thread when it's inside a try/except Modified: python/branches/py3k/Lib/test/test_tokenize.py ============================================================================== --- python/branches/py3k/Lib/test/test_tokenize.py (original) +++ python/branches/py3k/Lib/test/test_tokenize.py Fri Nov 13 03:25:08 2009 @@ -531,6 +531,24 @@ ... break ... else: True True + +Evil tabs + >>> dump_tokens("def f():\\n\\tif x\\n \\tpass") + ENCODING 'utf-8' (0, 0) (0, 0) + NAME 'def' (1, 0) (1, 3) + NAME 'f' (1, 4) (1, 5) + OP '(' (1, 5) (1, 6) + OP ')' (1, 6) (1, 7) + OP ':' (1, 7) (1, 8) + NEWLINE '\\n' (1, 8) (1, 9) + INDENT '\\t' (2, 0) (2, 1) + NAME 'if' (2, 1) (2, 3) + NAME 'x' (2, 4) (2, 5) + NEWLINE '\\n' (2, 5) (2, 6) + INDENT ' \\t' (3, 0) (3, 9) + NAME 'pass' (3, 9) (3, 13) + DEDENT '' (4, 0) (4, 0) + DEDENT '' (4, 0) (4, 0) """ from test import support Modified: python/branches/py3k/Lib/tokenize.py ============================================================================== --- python/branches/py3k/Lib/tokenize.py (original) +++ python/branches/py3k/Lib/tokenize.py Fri Nov 13 03:25:08 2009 @@ -23,15 +23,15 @@ __credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' 'Michael Foord') - import re, string, sys from token import * from codecs import lookup, BOM_UTF8 cookie_re = re.compile("coding[:=]\s*([-\w.]+)") import token -__all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", - "detect_encoding", "NL", "untokenize", "ENCODING", "TokenInfo"] +__all__ = [x for x in dir(token) if not x.startswith("_")] +__all__.extend(["COMMENT", "tokenize", "detect_encoding", "NL", "untokenize", + "ENCODING", "TokenInfo"]) del token COMMENT = N_TOKENS @@ -407,7 +407,7 @@ if encoding is not None: line = line.decode(encoding) - lnum = lnum + 1 + lnum += 1 pos, max = 0, len(line) if contstr: # continued string @@ -435,12 +435,17 @@ if not line: break column = 0 while pos < max: # measure leading whitespace - if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize - elif line[pos] == '\f': column = 0 - else: break - pos = pos + 1 - if pos == max: break + if line[pos] == ' ': + column += 1 + elif line[pos] == '\t': + column = (column//tabsize + 1)*tabsize + elif line[pos] == '\f': + column = 0 + else: + break + pos += 1 + if pos == max: + break if line[pos] in '#\r\n': # skip comments or blank lines if line[pos] == '#': @@ -516,13 +521,15 @@ elif initial == '\\': # continued stmt continued = 1 else: - if initial in '([{': parenlev = parenlev + 1 - elif initial in ')]}': parenlev = parenlev - 1 + if initial in '([{': + parenlev += 1 + elif initial in ')]}': + parenlev -= 1 yield TokenInfo(OP, token, spos, epos, line) else: yield TokenInfo(ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) - pos = pos + 1 + pos += 1 for indent in indents[1:]: # pop remaining indent levels yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') Modified: python/branches/py3k/Lib/xml/__init__.py ============================================================================== --- python/branches/py3k/Lib/xml/__init__.py (original) +++ python/branches/py3k/Lib/xml/__init__.py Fri Nov 13 03:25:08 2009 @@ -19,12 +19,6 @@ __all__ = ["dom", "parsers", "sax", "etree"] -# When being checked-out without options, this has the form -# "Revision: x.y " -# When exported using -kv, it is "x.y". -__version__ = "$Revision$".split()[-2:][0] - - _MINIMUM_XMLPLUS_VERSION = (0, 8, 4) Modified: python/branches/py3k/Misc/Porting ============================================================================== --- python/branches/py3k/Misc/Porting (original) +++ python/branches/py3k/Misc/Porting Fri Nov 13 03:25:08 2009 @@ -31,8 +31,7 @@ it out of the config.c file. Bang on it until you get a >>> prompt. (You may have to disable the -importing of "site.py" and "exceptions.py" by passing -X and -S -options. +importing of "site.py" by passing the -S options.) Then bang on it until it executes very simple Python statements. Modified: python/branches/py3k/Modules/_io/stringio.c ============================================================================== --- python/branches/py3k/Modules/_io/stringio.c (original) +++ python/branches/py3k/Modules/_io/stringio.c Fri Nov 13 03:25:08 2009 @@ -600,9 +600,6 @@ assert((newline != NULL && newline_obj != Py_None) || (newline == NULL && newline_obj == Py_None)); - assert((newline != NULL && newline_obj != Py_None) || - (newline == NULL && newline_obj == Py_None)); - if (newline) { self->readnl = PyUnicode_FromString(newline); if (self->readnl == NULL) Modified: python/branches/py3k/Modules/mathmodule.c ============================================================================== --- python/branches/py3k/Modules/mathmodule.c (original) +++ python/branches/py3k/Modules/mathmodule.c Fri Nov 13 03:25:08 2009 @@ -661,7 +661,7 @@ "This is the smallest integral value >= x."); FUNC2(copysign, copysign, - "copysign(x,y)\n\nReturn x with the sign of y.") + "copysign(x, y)\n\nReturn x with the sign of y.") FUNC1(cos, cos, 0, "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, 1, @@ -695,8 +695,8 @@ FUNC1A(gamma, m_tgamma, "gamma(x)\n\nGamma function at x.") FUNC1(log1p, log1p, 1, - "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n\ - The result is computed in a way which is accurate for x near zero.") + "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n" + "The result is computed in a way which is accurate for x near zero.") FUNC1(sin, sin, 0, "sin(x)\n\nReturn the sine of x (measured in radians).") FUNC1(sinh, sinh, 1, @@ -925,7 +925,7 @@ #undef NUM_PARTIALS PyDoc_STRVAR(math_fsum_doc, -"sum(iterable)\n\n\ +"fsum(iterable)\n\n\ Return an accurate floating point sum of values in the iterable.\n\ Assumes IEEE-754 floating point arithmetic."); @@ -1101,7 +1101,8 @@ } PyDoc_STRVAR(math_ldexp_doc, -"ldexp(x, i) -> x * (2**i)"); +"ldexp(x, i)\n\n\ +Return x * (2**i)."); static PyObject * math_modf(PyObject *self, PyObject *arg) @@ -1192,7 +1193,8 @@ } PyDoc_STRVAR(math_log_doc, -"log(x[, base]) -> the logarithm of x to the given base.\n\ +"log(x[, base])\n\n\ +Return the logarithm of x to the given base.\n\ If the base not specified, returns the natural logarithm (base e) of x."); static PyObject * @@ -1202,7 +1204,7 @@ } PyDoc_STRVAR(math_log10_doc, -"log10(x) -> the base 10 logarithm of x."); +"log10(x)\n\nReturn the base 10 logarithm of x."); static PyObject * math_fmod(PyObject *self, PyObject *args) @@ -1235,7 +1237,7 @@ } PyDoc_STRVAR(math_fmod_doc, -"fmod(x,y)\n\nReturn fmod(x, y), according to platform C." +"fmod(x, y)\n\nReturn fmod(x, y), according to platform C." " x % y may differ."); static PyObject * @@ -1277,7 +1279,7 @@ } PyDoc_STRVAR(math_hypot_doc, -"hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y)."); +"hypot(x, y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y)."); /* pow can't use math_2, but needs its own wrapper: the problem is that an infinite result can arise either as a result of overflow @@ -1364,7 +1366,7 @@ } PyDoc_STRVAR(math_pow_doc, -"pow(x,y)\n\nReturn x**y (x to the power of y)."); +"pow(x, y)\n\nReturn x**y (x to the power of y)."); static const double degToRad = Py_MATH_PI / 180.0; static const double radToDeg = 180.0 / Py_MATH_PI; @@ -1379,7 +1381,8 @@ } PyDoc_STRVAR(math_degrees_doc, -"degrees(x) -> converts angle x from radians to degrees"); +"degrees(x)\n\n\ +Convert angle x from radians to degrees."); static PyObject * math_radians(PyObject *self, PyObject *arg) @@ -1391,7 +1394,8 @@ } PyDoc_STRVAR(math_radians_doc, -"radians(x) -> converts angle x from degrees to radians"); +"radians(x)\n\n\ +Convert angle x from degrees to radians."); static PyObject * math_isnan(PyObject *self, PyObject *arg) @@ -1403,8 +1407,8 @@ } PyDoc_STRVAR(math_isnan_doc, -"isnan(x) -> bool\n\ -Checks if float x is not a number (NaN)"); +"isnan(x) -> bool\n\n\ +Check if float x is not a number (NaN)."); static PyObject * math_isinf(PyObject *self, PyObject *arg) @@ -1416,8 +1420,8 @@ } PyDoc_STRVAR(math_isinf_doc, -"isinf(x) -> bool\n\ -Checks if float x is infinite (positive or negative)"); +"isinf(x) -> bool\n\n\ +Check if float x is infinite (positive or negative)."); static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, Modified: python/branches/py3k/Modules/operator.c ============================================================================== --- python/branches/py3k/Modules/operator.c (original) +++ python/branches/py3k/Modules/operator.c Fri Nov 13 03:25:08 2009 @@ -7,7 +7,7 @@ This module exports a set of functions implemented in C corresponding\n\ to the intrinsic operators of Python. For example, operator.add(x, y)\n\ is equivalent to the expression x+y. The function names are those\n\ -used for special class methods; variants without leading and trailing\n\ +used for special methods; variants without leading and trailing\n\ '__' are also provided for convenience."); #define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \ @@ -197,21 +197,21 @@ spam2(and_,__and__, "and_(a, b) -- Same as a & b.") spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.") spam2(or_,__or__, "or_(a, b) -- Same as a | b.") -spam2(iadd,__iadd__, "iadd(a, b) -- Same as a += b.") -spam2(isub,__isub__, "isub(a, b) -- Same as a -= b.") -spam2(imul,__imul__, "imul(a, b) -- Same as a *= b.") -spam2(ifloordiv,__ifloordiv__, "ifloordiv(a, b) -- Same as a //= b.") -spam2(itruediv,__itruediv__, "itruediv(a, b) -- Same as a /= b.") -spam2(imod,__imod__, "imod(a, b) -- Same as a %= b.") -spam2(ilshift,__ilshift__, "ilshift(a, b) -- Same as a <<= b.") -spam2(irshift,__irshift__, "irshift(a, b) -- Same as a >>= b.") -spam2(iand,__iand__, "iand(a, b) -- Same as a &= b.") -spam2(ixor,__ixor__, "ixor(a, b) -- Same as a ^= b.") -spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.") +spam2(iadd,__iadd__, "a = iadd(a, b) -- Same as a += b.") +spam2(isub,__isub__, "a = isub(a, b) -- Same as a -= b.") +spam2(imul,__imul__, "a = imul(a, b) -- Same as a *= b.") +spam2(ifloordiv,__ifloordiv__, "a = ifloordiv(a, b) -- Same as a //= b.") +spam2(itruediv,__itruediv__, "a = itruediv(a, b) -- Same as a /= b") +spam2(imod,__imod__, "a = imod(a, b) -- Same as a %= b.") +spam2(ilshift,__ilshift__, "a = ilshift(a, b) -- Same as a <<= b.") +spam2(irshift,__irshift__, "a = irshift(a, b) -- Same as a >>= b.") +spam2(iand,__iand__, "a = iand(a, b) -- Same as a &= b.") +spam2(ixor,__ixor__, "a = ixor(a, b) -- Same as a ^= b.") +spam2(ior,__ior__, "a = ior(a, b) -- Same as a |= b.") spam2(concat,__concat__, "concat(a, b) -- Same as a + b, for a and b sequences.") spam2(iconcat,__iconcat__, - "iconcat(a, b) -- Same as a += b, for a and b sequences.") + "a = iconcat(a, b) -- Same as a += b, for a and b sequences.") spam2(getitem,__getitem__, "getitem(a, b) -- Same as a[b].") spam2(setitem,__setitem__, @@ -219,7 +219,7 @@ spam2(delitem,__delitem__, "delitem(a, b) -- Same as del a[b].") spam2(pow,__pow__, "pow(a, b) -- Same as a ** b.") -spam2(ipow,__ipow__, "ipow(a, b) -- Same as a **= b.") +spam2(ipow,__ipow__, "a = ipow(a, b) -- Same as a **= b.") spam2(lt,__lt__, "lt(a, b) -- Same as aprop_doc); prop->prop_doc = get_doc; - } else { - /* Put __doc__ in dict of the subclass instance instead, - otherwise it gets shadowed by class's __doc__. */ - if (PyObject_SetAttrString(self, "__doc__", get_doc) != 0) - { - /* DECREF for props handled by _dealloc */ - Py_DECREF(get_doc); + } + else { + /* If this is a property subclass, put __doc__ + in dict of the subclass instance instead, + otherwise it gets shadowed by __doc__ in the + class's dict. */ + int err = PyObject_SetAttrString(self, "__doc__", get_doc); + Py_DECREF(get_doc); + if (err < 0) return -1; - } - Py_DECREF(get_doc); } prop->getter_doc = 1; - } else { + } + else if (PyErr_ExceptionMatches(PyExc_Exception)) { PyErr_Clear(); } + else { + return -1; + } } return 0; Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Fri Nov 13 03:25:08 2009 @@ -183,9 +183,12 @@ return NULL; } if (i < 0 || i >= Py_SIZE(op)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } @@ -406,9 +409,12 @@ list_item(PyListObject *a, Py_ssize_t i) { if (i < 0 || i >= Py_SIZE(a)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } Modified: python/branches/py3k/Objects/moduleobject.c ============================================================================== --- python/branches/py3k/Objects/moduleobject.c (original) +++ python/branches/py3k/Objects/moduleobject.c Fri Nov 13 03:25:08 2009 @@ -312,7 +312,10 @@ if (m->md_def && m->md_def->m_free) m->md_def->m_free(m); if (m->md_dict != NULL) { - _PyModule_Clear((PyObject *)m); + /* If we are the only ones holding a reference, we can clear + the dictionary. */ + if (Py_REFCNT(m->md_dict) == 1) + _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } if (m->md_state != NULL) Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Fri Nov 13 03:25:08 2009 @@ -197,20 +197,26 @@ int i; for (i = 0; i < 12; i++) { int c = s[i]; - if (c == '\0') break; - else if (c == '_') buf[i] = '-'; - else buf[i] = tolower(c); + if (c == '\0') + break; + else if (c == '_') + buf[i] = '-'; + else + buf[i] = tolower(c); } buf[i] = '\0'; if (strcmp(buf, "utf-8") == 0 || - strncmp(buf, "utf-8-", 6) == 0) return "utf-8"; + strncmp(buf, "utf-8-", 6) == 0) + return "utf-8"; else if (strcmp(buf, "latin-1") == 0 || strcmp(buf, "iso-8859-1") == 0 || strcmp(buf, "iso-latin-1") == 0 || strncmp(buf, "latin-1-", 8) == 0 || strncmp(buf, "iso-8859-1-", 11) == 0 || - strncmp(buf, "iso-latin-1-", 12) == 0) return "iso-8859-1"; - else return s; + strncmp(buf, "iso-latin-1-", 12) == 0) + return "iso-8859-1"; + else + return s; } /* Return the coding spec in S, or NULL if none is found. */ @@ -336,12 +342,18 @@ /* Disable support for UTF-16 BOMs until a decision is made whether this needs to be supported. */ } else if (ch == 0xFE) { - ch = get_char(tok); if (ch != 0xFF) goto NON_BOM; - if (!set_readline(tok, "utf-16-be")) return 0; + ch = get_char(tok); + if (ch != 0xFF) + goto NON_BOM; + if (!set_readline(tok, "utf-16-be")) + return 0; tok->decoding_state = STATE_NORMAL; } else if (ch == 0xFF) { - ch = get_char(tok); if (ch != 0xFE) goto NON_BOM; - if (!set_readline(tok, "utf-16-le")) return 0; + ch = get_char(tok); + if (ch != 0xFE) + goto NON_BOM; + if (!set_readline(tok, "utf-16-le")) + return 0; tok->decoding_state = STATE_NORMAL; #endif } else { @@ -1036,7 +1048,7 @@ { if (c != EOF) { if (--tok->cur < tok->buf) - Py_FatalError("tok_backup: begin of buffer"); + Py_FatalError("tok_backup: beginning of buffer"); if (*tok->cur != c) *tok->cur = c; } From python-checkins at python.org Fri Nov 13 03:29:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 02:29:36 -0000 Subject: [Python-checkins] r76236 - in python/branches/release31-maint: Doc/distutils/apiref.rst Doc/distutils/examples.rst Doc/library/2to3.rst Doc/library/bdb.rst Doc/library/io.rst Doc/library/operator.rst Doc/library/pdb.rst Doc/library/profile.rst Doc/library/pty.rst Doc/library/turtle.rst Doc/library/weakref.rst Doc/library/zipfile.rst Doc/whatsnew/2.6.rst Lib/distutils/command/check.py Lib/inspect.py Lib/test/test_ast.py Lib/test/test_inspect.py Lib/test/test_module.py Lib/test/test_strptime.py Lib/test/test_tokenize.py Lib/tokenize.py Lib/xml/__init__.py Misc/Porting Modules/mathmodule.c Modules/operator.c Objects/descrobject.c Objects/listobject.c Objects/moduleobject.c Parser/tokenizer.c Message-ID: Author: benjamin.peterson Date: Fri Nov 13 03:29:35 2009 New Revision: 76236 Log: Merged revisions 76235 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76235 | benjamin.peterson | 2009-11-12 20:25:08 -0600 (Thu, 12 Nov 2009) | 170 lines Merged revisions 75149,75260-75263,75265-75267,75292,75300,75376,75405,75429-75433,75437,75445,75501,75551,75572,75589-75591,75657,75742,75868,75952-75957,76057,76105,76139,76143,76162,76223 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75149 | gregory.p.smith | 2009-09-29 16:56:31 -0500 (Tue, 29 Sep 2009) | 3 lines Mention issue6972 in extractall docs about overwriting things outside of the supplied path. ........ r75260 | andrew.kuchling | 2009-10-05 16:24:20 -0500 (Mon, 05 Oct 2009) | 1 line Wording fix ........ r75261 | andrew.kuchling | 2009-10-05 16:24:35 -0500 (Mon, 05 Oct 2009) | 1 line Fix narkup ........ r75262 | andrew.kuchling | 2009-10-05 16:25:03 -0500 (Mon, 05 Oct 2009) | 1 line Document 'skip' parameter to constructor ........ r75263 | andrew.kuchling | 2009-10-05 16:25:35 -0500 (Mon, 05 Oct 2009) | 1 line Note side benefit of socket.create_connection() ........ r75265 | andrew.kuchling | 2009-10-05 17:31:11 -0500 (Mon, 05 Oct 2009) | 1 line Reword sentence ........ r75266 | andrew.kuchling | 2009-10-05 17:32:48 -0500 (Mon, 05 Oct 2009) | 1 line Use standard comma punctuation; reword some sentences in the docs ........ r75267 | andrew.kuchling | 2009-10-05 17:42:56 -0500 (Mon, 05 Oct 2009) | 1 line Backport r73983: Document the thousands separator. ........ r75292 | benjamin.peterson | 2009-10-08 22:11:36 -0500 (Thu, 08 Oct 2009) | 1 line death to old CVS keyword ........ r75300 | benjamin.peterson | 2009-10-09 16:48:14 -0500 (Fri, 09 Oct 2009) | 1 line fix some coding style ........ r75376 | benjamin.peterson | 2009-10-11 20:26:07 -0500 (Sun, 11 Oct 2009) | 1 line platform we don't care about ........ r75405 | neil.schemenauer | 2009-10-14 12:17:14 -0500 (Wed, 14 Oct 2009) | 4 lines Issue #1754094: Improve the stack depth calculation in the compiler. There should be no other effect than a small decrease in memory use. Patch by Christopher Tur Lesniewski-Laas. ........ r75429 | benjamin.peterson | 2009-10-14 20:47:28 -0500 (Wed, 14 Oct 2009) | 1 line pep8ify if blocks ........ r75430 | benjamin.peterson | 2009-10-14 20:49:37 -0500 (Wed, 14 Oct 2009) | 1 line use floor division and add a test that exercises the tabsize codepath ........ r75431 | benjamin.peterson | 2009-10-14 20:56:25 -0500 (Wed, 14 Oct 2009) | 1 line change test to what I intended ........ r75432 | benjamin.peterson | 2009-10-14 22:05:39 -0500 (Wed, 14 Oct 2009) | 1 line some cleanups ........ r75433 | benjamin.peterson | 2009-10-14 22:06:55 -0500 (Wed, 14 Oct 2009) | 1 line make inspect.isabstract() always return a boolean; add a test for it, too #7069 ........ r75437 | benjamin.peterson | 2009-10-15 10:44:46 -0500 (Thu, 15 Oct 2009) | 1 line only clear a module's __dict__ if the module is the only one with a reference to it #7140 ........ r75445 | vinay.sajip | 2009-10-16 09:06:44 -0500 (Fri, 16 Oct 2009) | 1 line Issue #7120: logging: Removed import of multiprocessing which is causing crash in GAE. ........ r75501 | antoine.pitrou | 2009-10-18 13:37:11 -0500 (Sun, 18 Oct 2009) | 3 lines Add a comment about unreachable code, and fix a typo ........ r75551 | benjamin.peterson | 2009-10-19 22:14:10 -0500 (Mon, 19 Oct 2009) | 1 line use property api ........ r75572 | benjamin.peterson | 2009-10-20 16:55:17 -0500 (Tue, 20 Oct 2009) | 1 line clarify buffer arg #7178 ........ r75589 | benjamin.peterson | 2009-10-21 21:26:47 -0500 (Wed, 21 Oct 2009) | 1 line whitespace ........ r75590 | benjamin.peterson | 2009-10-21 21:36:47 -0500 (Wed, 21 Oct 2009) | 1 line rewrite to be nice to other implementations ........ r75591 | benjamin.peterson | 2009-10-21 21:50:38 -0500 (Wed, 21 Oct 2009) | 4 lines rewrite for style, clarify, and comments Also, use the hasattr() like scheme of allowing BaseException exceptions through. ........ r75657 | antoine.pitrou | 2009-10-24 07:41:27 -0500 (Sat, 24 Oct 2009) | 3 lines Fix compilation error in debug mode. ........ r75742 | benjamin.peterson | 2009-10-26 17:51:16 -0500 (Mon, 26 Oct 2009) | 1 line use 'is' instead of id() ........ r75868 | benjamin.peterson | 2009-10-27 15:59:18 -0500 (Tue, 27 Oct 2009) | 1 line test expect base classes ........ r75952 | georg.brandl | 2009-10-29 15:38:32 -0500 (Thu, 29 Oct 2009) | 1 line Use the correct function name in docstring. ........ r75953 | georg.brandl | 2009-10-29 15:39:50 -0500 (Thu, 29 Oct 2009) | 1 line Remove mention of the old -X command line switch. ........ r75954 | georg.brandl | 2009-10-29 15:53:00 -0500 (Thu, 29 Oct 2009) | 1 line Use constants instead of magic integers for test result. Do not re-run with --verbose3 for environment changing tests. ........ r75955 | georg.brandl | 2009-10-29 15:54:03 -0500 (Thu, 29 Oct 2009) | 1 line Use a single style for all the docstrings in the math module. ........ r75956 | georg.brandl | 2009-10-29 16:16:34 -0500 (Thu, 29 Oct 2009) | 1 line I do not think the "railroad" program mentioned is still available. ........ r75957 | georg.brandl | 2009-10-29 16:44:56 -0500 (Thu, 29 Oct 2009) | 1 line Fix constant name. ........ r76057 | benjamin.peterson | 2009-11-02 09:06:45 -0600 (Mon, 02 Nov 2009) | 1 line prevent a rather unlikely segfault ........ r76105 | georg.brandl | 2009-11-04 01:38:12 -0600 (Wed, 04 Nov 2009) | 1 line #7259: show correct equivalent for operator.i* operations in docstring; fix minor issues in operator docs. ........ r76139 | benjamin.peterson | 2009-11-06 19:04:38 -0600 (Fri, 06 Nov 2009) | 1 line spelling ........ r76143 | georg.brandl | 2009-11-07 02:26:07 -0600 (Sat, 07 Nov 2009) | 1 line #7271: fix typo. ........ r76162 | benjamin.peterson | 2009-11-08 22:10:53 -0600 (Sun, 08 Nov 2009) | 1 line discuss how to use -p ........ r76223 | georg.brandl | 2009-11-12 02:29:46 -0600 (Thu, 12 Nov 2009) | 1 line Give the profile module a module directive. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/distutils/apiref.rst python/branches/release31-maint/Doc/distutils/examples.rst python/branches/release31-maint/Doc/library/2to3.rst python/branches/release31-maint/Doc/library/bdb.rst python/branches/release31-maint/Doc/library/io.rst python/branches/release31-maint/Doc/library/operator.rst python/branches/release31-maint/Doc/library/pdb.rst python/branches/release31-maint/Doc/library/profile.rst python/branches/release31-maint/Doc/library/pty.rst python/branches/release31-maint/Doc/library/turtle.rst python/branches/release31-maint/Doc/library/weakref.rst python/branches/release31-maint/Doc/library/zipfile.rst python/branches/release31-maint/Doc/whatsnew/2.6.rst python/branches/release31-maint/Lib/distutils/command/check.py python/branches/release31-maint/Lib/inspect.py python/branches/release31-maint/Lib/test/test_ast.py python/branches/release31-maint/Lib/test/test_inspect.py python/branches/release31-maint/Lib/test/test_module.py python/branches/release31-maint/Lib/test/test_strptime.py python/branches/release31-maint/Lib/test/test_tokenize.py python/branches/release31-maint/Lib/tokenize.py python/branches/release31-maint/Lib/xml/__init__.py python/branches/release31-maint/Misc/Porting python/branches/release31-maint/Modules/mathmodule.c python/branches/release31-maint/Modules/operator.c python/branches/release31-maint/Objects/descrobject.c python/branches/release31-maint/Objects/listobject.c python/branches/release31-maint/Objects/moduleobject.c python/branches/release31-maint/Parser/tokenizer.c Modified: python/branches/release31-maint/Doc/distutils/apiref.rst ============================================================================== --- python/branches/release31-maint/Doc/distutils/apiref.rst (original) +++ python/branches/release31-maint/Doc/distutils/apiref.rst Fri Nov 13 03:29:35 2009 @@ -1952,7 +1952,7 @@ The ``check`` command performs some tests on the meta-data of a package. -It makes sure for example that all required meta-data are provided through +For example, it verifies that all required meta-data are provided as the arguments passed to the :func:`setup` function. .. % todo Modified: python/branches/release31-maint/Doc/distutils/examples.rst ============================================================================== --- python/branches/release31-maint/Doc/distutils/examples.rst (original) +++ python/branches/release31-maint/Doc/distutils/examples.rst Fri Nov 13 03:29:35 2009 @@ -236,10 +236,10 @@ Checking a package ================== -The ``check`` command allows you to verify if your package meta-data are -meeting the minimum requirements to build a distribution. +The ``check`` command allows you to verify if your package meta-data +meet the minimum requirements to build a distribution. -To run it, just call it over your :file:`setup.py` script. If something is +To run it, just call it using your :file:`setup.py` script. If something is missing, ``check`` will display a warning. Let's take an example with a simple script:: @@ -252,7 +252,7 @@ $ python setup.py check running check - warning: check: missing required meta-data: version ,url + warning: check: missing required meta-data: version, url warning: check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) must be supplied Modified: python/branches/release31-maint/Doc/library/2to3.rst ============================================================================== --- python/branches/release31-maint/Doc/library/2to3.rst (original) +++ python/branches/release31-maint/Doc/library/2to3.rst Fri Nov 13 03:29:35 2009 @@ -86,6 +86,14 @@ The :option:`-v` option enables output of more information on the translation process. +Since some print statements can be parsed as function calls or statements, 2to3 +cannot always read files containing the print function. When 2to3 detects the +presence of the ``from __future__ import print_function`` compiler directive, it +modifies its internal grammar to interpert :func:`print` as a function. This +change can also be enabled manually with the :option:`-p` flag. Use +:option:`-p` to run fixers on code that already has had its print statements +converted. + .. _2to3-fixers: Modified: python/branches/release31-maint/Doc/library/bdb.rst ============================================================================== --- python/branches/release31-maint/Doc/library/bdb.rst (original) +++ python/branches/release31-maint/Doc/library/bdb.rst Fri Nov 13 03:29:35 2009 @@ -62,14 +62,22 @@ * The breakpoint hit count. -.. class:: Bdb() +.. class:: Bdb(skip=None) - The :class:`Bdb` acts as a generic Python debugger base class. + The :class:`Bdb` class acts as a generic Python debugger base class. This class takes care of the details of the trace facility; a derived class should implement user interaction. The standard debugger class (:class:`pdb.Pdb`) is an example. + The *skip* argument, if given, must be an iterable of glob-style + module name patterns. The debugger will not step into frames that + originate in a module that matches one of these patterns. Whether a + frame is considered to originate in a certain module is determined + by the ``__name__`` in the frame globals. + + .. versionadded:: 2.7 + The *skip* argument. The following methods of :class:`Bdb` normally don't need to be overridden. Modified: python/branches/release31-maint/Doc/library/io.rst ============================================================================== --- python/branches/release31-maint/Doc/library/io.rst (original) +++ python/branches/release31-maint/Doc/library/io.rst Fri Nov 13 03:29:35 2009 @@ -98,8 +98,8 @@ *buffering* is an optional integer used to set the buffering policy. By default full buffering is on. Pass 0 to switch buffering off (only allowed - in binary mode), 1 to set line buffering, and an integer > 1 for full - buffering. + in binary mode), 1 to set line buffering, and an integer > 1 to indicate the + size of the buffer. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform Modified: python/branches/release31-maint/Doc/library/operator.rst ============================================================================== --- python/branches/release31-maint/Doc/library/operator.rst (original) +++ python/branches/release31-maint/Doc/library/operator.rst Fri Nov 13 03:29:35 2009 @@ -104,6 +104,14 @@ Return ``a // b``. +.. function:: index(a) + __index__(a) + + Return *a* converted to an integer. Equivalent to ``a.__index__()``. + + .. versionadded:: 2.5 + + .. function:: inv(obj) invert(obj) __inv__(obj) @@ -133,7 +141,7 @@ .. function:: neg(obj) __neg__(obj) - Return *obj* negated. + Return *obj* negated (``-obj``). .. function:: or_(a, b) @@ -145,7 +153,7 @@ .. function:: pos(obj) __pos__(obj) - Return *obj* positive. + Return *obj* positive (``+obj``). .. function:: pow(a, b) @@ -179,13 +187,7 @@ Return the bitwise exclusive or of *a* and *b*. -.. function:: index(a) - __index__(a) - - Return *a* converted to an integer. Equivalent to ``a.__index__()``. - - -Operations which work with sequences include: +Operations which work with sequences (some of them with mappings too) include: .. function:: concat(a, b) __concat__(a, b) @@ -394,67 +396,77 @@ This table shows how abstract operations correspond to operator symbols in the Python syntax and the functions in the :mod:`operator` module. -+-----------------------+-------------------------+---------------------------------+ -| Operation | Syntax | Function | -+=======================+=========================+=================================+ -| Addition | ``a + b`` | ``add(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Concatenation | ``seq1 + seq2`` | ``concat(seq1, seq2)`` | -+-----------------------+-------------------------+---------------------------------+ -| Containment Test | ``obj in seq`` | ``contains(seq, obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a / b`` | ``truediv(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Division | ``a // b`` | ``floordiv(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise And | ``a & b`` | ``and_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Exclusive Or | ``a ^ b`` | ``xor(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Inversion | ``~ a`` | ``invert(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Bitwise Or | ``a | b`` | ``or_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Exponentiation | ``a ** b`` | ``pow(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Identity | ``a is b`` | ``is_(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Identity | ``a is not b`` | ``is_not(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexed Assignment | ``obj[k] = v`` | ``setitem(obj, k, v)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexed Deletion | ``del obj[k]`` | ``delitem(obj, k)`` | -+-----------------------+-------------------------+---------------------------------+ -| Indexing | ``obj[k]`` | ``getitem(obj, k)`` | -+-----------------------+-------------------------+---------------------------------+ -| Left Shift | ``a << b`` | ``lshift(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Modulo | ``a % b`` | ``mod(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Multiplication | ``a * b`` | ``mul(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Negation (Arithmetic) | ``- a`` | ``neg(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Negation (Logical) | ``not a`` | ``not_(a)`` | -+-----------------------+-------------------------+---------------------------------+ -| Right Shift | ``a >> b`` | ``rshift(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| String Formatting | ``s % obj`` | ``mod(s, obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Subtraction | ``a - b`` | ``sub(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Truth Test | ``obj`` | ``truth(obj)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a < b`` | ``lt(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a <= b`` | ``le(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Equality | ``a == b`` | ``eq(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Difference | ``a != b`` | ``ne(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a >= b`` | ``ge(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ -| Ordering | ``a > b`` | ``gt(a, b)`` | -+-----------------------+-------------------------+---------------------------------+ ++-----------------------+-------------------------+---------------------------------------+ +| Operation | Syntax | Function | ++=======================+=========================+=======================================+ +| Addition | ``a + b`` | ``add(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Concatenation | ``seq1 + seq2`` | ``concat(seq1, seq2)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Containment Test | ``obj in seq`` | ``contains(seq, obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a / b`` | ``div(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Division | ``a // b`` | ``floordiv(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise And | ``a & b`` | ``and_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Exclusive Or | ``a ^ b`` | ``xor(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Inversion | ``~ a`` | ``invert(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Bitwise Or | ``a | b`` | ``or_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Exponentiation | ``a ** b`` | ``pow(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Identity | ``a is b`` | ``is_(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Identity | ``a is not b`` | ``is_not(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexed Assignment | ``obj[k] = v`` | ``setitem(obj, k, v)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexed Deletion | ``del obj[k]`` | ``delitem(obj, k)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Indexing | ``obj[k]`` | ``getitem(obj, k)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Left Shift | ``a << b`` | ``lshift(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Modulo | ``a % b`` | ``mod(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Multiplication | ``a * b`` | ``mul(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Negation (Arithmetic) | ``- a`` | ``neg(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Negation (Logical) | ``not a`` | ``not_(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Positive | ``+ a`` | ``pos(a)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Right Shift | ``a >> b`` | ``rshift(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Sequence Repetition | ``seq * i`` | ``repeat(seq, i)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slice Assignment | ``seq[i:j] = values`` | ``setitem(seq, slice(i, j), values)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slice Deletion | ``del seq[i:j]`` | ``delitem(seq, slice(i, j))`` | ++-----------------------+-------------------------+---------------------------------------+ +| Slicing | ``seq[i:j]`` | ``getitem(seq, slice(i, j))`` | ++-----------------------+-------------------------+---------------------------------------+ +| String Formatting | ``s % obj`` | ``mod(s, obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Subtraction | ``a - b`` | ``sub(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Truth Test | ``obj`` | ``truth(obj)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a < b`` | ``lt(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a <= b`` | ``le(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Equality | ``a == b`` | ``eq(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Difference | ``a != b`` | ``ne(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a >= b`` | ``ge(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ +| Ordering | ``a > b`` | ``gt(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ Modified: python/branches/release31-maint/Doc/library/pdb.rst ============================================================================== --- python/branches/release31-maint/Doc/library/pdb.rst (original) +++ python/branches/release31-maint/Doc/library/pdb.rst Fri Nov 13 03:29:35 2009 @@ -55,7 +55,7 @@ import pdb; pdb.set_trace() at the location you want to break into the debugger. You can then step through -the code following this statement, and continue running without debugger using +the code following this statement, and continue running without the debugger using the ``c`` command. The typical usage to inspect a crashed program is:: Modified: python/branches/release31-maint/Doc/library/profile.rst ============================================================================== --- python/branches/release31-maint/Doc/library/profile.rst (original) +++ python/branches/release31-maint/Doc/library/profile.rst Fri Nov 13 03:29:35 2009 @@ -7,6 +7,8 @@ .. sectionauthor:: James Roskind +.. module:: profile + :synopsis: Python source profiler. .. index:: single: InfoSeek Corporation Modified: python/branches/release31-maint/Doc/library/pty.rst ============================================================================== --- python/branches/release31-maint/Doc/library/pty.rst (original) +++ python/branches/release31-maint/Doc/library/pty.rst Fri Nov 13 03:29:35 2009 @@ -3,8 +3,8 @@ ======================================== .. module:: pty - :platform: IRIX, Linux - :synopsis: Pseudo-Terminal Handling for SGI and Linux. + :platform: Linux + :synopsis: Pseudo-Terminal Handling for Linux. .. moduleauthor:: Steen Lumholt .. sectionauthor:: Moshe Zadka @@ -14,8 +14,8 @@ controlling terminal programmatically. Because pseudo-terminal handling is highly platform dependent, there is code to -do it only for SGI and Linux. (The Linux code is supposed to work on other -platforms, but hasn't been tested yet.) +do it only for Linux. (The Linux code is supposed to work on other platforms, +but hasn't been tested yet.) The :mod:`pty` module defines the following functions: @@ -32,8 +32,8 @@ .. function:: openpty() Open a new pseudo-terminal pair, using :func:`os.openpty` if possible, or - emulation code for SGI and generic Unix systems. Return a pair of file - descriptors ``(master, slave)``, for the master and the slave end, respectively. + emulation code for generic Unix systems. Return a pair of file descriptors + ``(master, slave)``, for the master and the slave end, respectively. .. function:: spawn(argv[, master_read[, stdin_read]]) Modified: python/branches/release31-maint/Doc/library/turtle.rst ============================================================================== --- python/branches/release31-maint/Doc/library/turtle.rst (original) +++ python/branches/release31-maint/Doc/library/turtle.rst Fri Nov 13 03:29:35 2009 @@ -2023,7 +2023,7 @@ Subclass of TurtleScreen, with :ref:`four methods added `. -.. class:: ScrolledCavas(master) +.. class:: ScrolledCanvas(master) :param master: some Tkinter widget to contain the ScrolledCanvas, i.e. a Tkinter-canvas with scrollbars added Modified: python/branches/release31-maint/Doc/library/weakref.rst ============================================================================== --- python/branches/release31-maint/Doc/library/weakref.rst (original) +++ python/branches/release31-maint/Doc/library/weakref.rst Fri Nov 13 03:29:35 2009 @@ -69,10 +69,9 @@ obj = Dict(red=1, green=2, blue=3) # this object is weak referenceable -.. impl-detail:: - - Other built-in types such as :class:`tuple` and :class:`long` do not support - weak references even when subclassed. +Other built-in types such as :class:`tuple` and :class:`long` do not support +weak references even when subclassed (This is an implementation detail and may +be different across various Python implementations.). Extension types can easily be made to support weak references; see :ref:`weakref-support`. Modified: python/branches/release31-maint/Doc/library/zipfile.rst ============================================================================== --- python/branches/release31-maint/Doc/library/zipfile.rst (original) +++ python/branches/release31-maint/Doc/library/zipfile.rst Fri Nov 13 03:29:35 2009 @@ -197,6 +197,13 @@ be a subset of the list returned by :meth:`namelist`. *pwd* is the password used for encrypted files. + .. warning:: + + Never extract archives from untrusted sources without prior inspection. + It is possible that files are created outside of *path*, e.g. members + that have absolute filenames starting with ``"/"`` or filenames with two + dots ``".."``. + .. method:: ZipFile.printdir() Modified: python/branches/release31-maint/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/release31-maint/Doc/whatsnew/2.6.rst (original) +++ python/branches/release31-maint/Doc/whatsnew/2.6.rst Fri Nov 13 03:29:35 2009 @@ -2416,9 +2416,13 @@ environments. TIPC addresses are 4- or 5-tuples. (Contributed by Alberto Bertogli; :issue:`1646`.) - A new function, :func:`create_connection`, takes an address - and connects to it using an optional timeout value, returning - the connected socket object. + A new function, :func:`create_connection`, takes an address and + connects to it using an optional timeout value, returning the + connected socket object. This function also looks up the address's + type and connects to it using IPv4 or IPv6 as appropriate. Changing + your code to use :func:`create_connection` instead of + ``socket(socket.AF_INET, ...)`` may be all that's required to make + your code work with IPv6. * The base classes in the :mod:`SocketServer` module now support calling a :meth:`handle_timeout` method after a span of inactivity Modified: python/branches/release31-maint/Lib/distutils/command/check.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/command/check.py (original) +++ python/branches/release31-maint/Lib/distutils/command/check.py Fri Nov 13 03:29:35 2009 @@ -92,7 +92,7 @@ missing.append(attr) if missing: - self.warn("missing required meta-data: %s" % ' ,'.join(missing)) + self.warn("missing required meta-data: %s" % ', '.join(missing)) if metadata.author: if not metadata.author_email: self.warn("missing meta-data: if 'author' supplied, " + Modified: python/branches/release31-maint/Lib/inspect.py ============================================================================== --- python/branches/release31-maint/Lib/inspect.py (original) +++ python/branches/release31-maint/Lib/inspect.py Fri Nov 13 03:29:35 2009 @@ -238,7 +238,7 @@ def isabstract(object): """Return true if the object is an abstract base class (ABC).""" - return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT + return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT) def getmembers(object, predicate=None): """Return all members of an object as (name, value) pairs sorted by name. Modified: python/branches/release31-maint/Lib/test/test_ast.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_ast.py (original) +++ python/branches/release31-maint/Lib/test/test_ast.py Fri Nov 13 03:29:35 2009 @@ -140,6 +140,14 @@ self.assertEquals(to_tuple(ast_tree), o) self._assertTrueorder(ast_tree, (0, 0)) + def test_base_classes(self): + self.assertTrue(issubclass(ast.For, ast.stmt)) + self.assertTrue(issubclass(ast.Name, ast.expr)) + self.assertTrue(issubclass(ast.stmt, ast.AST)) + self.assertTrue(issubclass(ast.expr, ast.AST)) + self.assertTrue(issubclass(ast.comprehension, ast.AST)) + self.assertTrue(issubclass(ast.Gt, ast.AST)) + def test_nodeclasses(self): x = ast.BinOp(1, 2, 3, lineno=0) self.assertEquals(x.left, 1) Modified: python/branches/release31-maint/Lib/test/test_inspect.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_inspect.py (original) +++ python/branches/release31-maint/Lib/test/test_inspect.py Fri Nov 13 03:29:35 2009 @@ -120,6 +120,28 @@ self.assertTrue('a' in members) self.assertTrue('b' not in members) + def test_isabstract(self): + from abc import ABCMeta, abstractmethod + + class AbstractClassExample(metaclass=ABCMeta): + + @abstractmethod + def foo(self): + pass + + class ClassExample(AbstractClassExample): + def foo(self): + pass + + a = ClassExample() + + # Test general behaviour. + self.assertTrue(inspect.isabstract(AbstractClassExample)) + self.assertFalse(inspect.isabstract(ClassExample)) + self.assertFalse(inspect.isabstract(a)) + self.assertFalse(inspect.isabstract(int)) + self.assertFalse(inspect.isabstract(5)) + class TestInterpreterStack(IsTestBase): def __init__(self, *args, **kwargs): Modified: python/branches/release31-maint/Lib/test/test_module.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_module.py (original) +++ python/branches/release31-maint/Lib/test/test_module.py Fri Nov 13 03:29:35 2009 @@ -55,6 +55,14 @@ {"__name__": "foo", "__doc__": "foodoc", "bar": 42}) self.assertTrue(foo.__dict__ is d) + def test_dont_clear_dict(self): + # See issue 7140. + def f(): + foo = ModuleType("foo") + foo.bar = 4 + return foo + self.assertEqual(f().__dict__["bar"], 4) + def test_main(): run_unittest(ModuleTests) Modified: python/branches/release31-maint/Lib/test/test_strptime.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_strptime.py (original) +++ python/branches/release31-maint/Lib/test/test_strptime.py Fri Nov 13 03:29:35 2009 @@ -493,9 +493,9 @@ _strptime._strptime_time("10", "%d") _strptime._strptime_time("2005", "%Y") _strptime._TimeRE_cache.locale_time.lang = "Ni" - original_time_re = id(_strptime._TimeRE_cache) + original_time_re = _strptime._TimeRE_cache _strptime._strptime_time("10", "%d") - self.assertNotEqual(original_time_re, id(_strptime._TimeRE_cache)) + self.assertIsNot(original_time_re, _strptime._TimeRE_cache) self.assertEqual(len(_strptime._regex_cache), 1) def test_regex_cleanup(self): @@ -514,11 +514,10 @@ def test_new_localetime(self): # A new LocaleTime instance should be created when a new TimeRE object # is created. - locale_time_id = id(_strptime._TimeRE_cache.locale_time) + locale_time_id = _strptime._TimeRE_cache.locale_time _strptime._TimeRE_cache.locale_time.lang = "Ni" _strptime._strptime_time("10", "%d") - self.assertNotEqual(locale_time_id, - id(_strptime._TimeRE_cache.locale_time)) + self.assertIsNot(locale_time_id, _strptime._TimeRE_cache.locale_time) def test_TimeRE_recreation(self): # The TimeRE instance should be recreated upon changing the locale. @@ -530,15 +529,15 @@ try: _strptime._strptime_time('10', '%d') # Get id of current cache object. - first_time_re_id = id(_strptime._TimeRE_cache) + first_time_re = _strptime._TimeRE_cache try: # Change the locale and force a recreation of the cache. locale.setlocale(locale.LC_TIME, ('de_DE', 'UTF8')) _strptime._strptime_time('10', '%d') # Get the new cache object's id. - second_time_re_id = id(_strptime._TimeRE_cache) + second_time_re = _strptime._TimeRE_cache # They should not be equal. - self.assertNotEqual(first_time_re_id, second_time_re_id) + self.assertIsNot(first_time_re, second_time_re) # Possible test locale is not supported while initial locale is. # If this is the case just suppress the exception and fall-through # to the reseting to the original locale. Modified: python/branches/release31-maint/Lib/test/test_tokenize.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tokenize.py (original) +++ python/branches/release31-maint/Lib/test/test_tokenize.py Fri Nov 13 03:29:35 2009 @@ -531,6 +531,24 @@ ... break ... else: True True + +Evil tabs + >>> dump_tokens("def f():\\n\\tif x\\n \\tpass") + ENCODING 'utf-8' (0, 0) (0, 0) + NAME 'def' (1, 0) (1, 3) + NAME 'f' (1, 4) (1, 5) + OP '(' (1, 5) (1, 6) + OP ')' (1, 6) (1, 7) + OP ':' (1, 7) (1, 8) + NEWLINE '\\n' (1, 8) (1, 9) + INDENT '\\t' (2, 0) (2, 1) + NAME 'if' (2, 1) (2, 3) + NAME 'x' (2, 4) (2, 5) + NEWLINE '\\n' (2, 5) (2, 6) + INDENT ' \\t' (3, 0) (3, 9) + NAME 'pass' (3, 9) (3, 13) + DEDENT '' (4, 0) (4, 0) + DEDENT '' (4, 0) (4, 0) """ from test import support Modified: python/branches/release31-maint/Lib/tokenize.py ============================================================================== --- python/branches/release31-maint/Lib/tokenize.py (original) +++ python/branches/release31-maint/Lib/tokenize.py Fri Nov 13 03:29:35 2009 @@ -23,15 +23,15 @@ __credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' 'Michael Foord') - import re, string, sys from token import * from codecs import lookup, BOM_UTF8 cookie_re = re.compile("coding[:=]\s*([-\w.]+)") import token -__all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", - "detect_encoding", "NL", "untokenize", "ENCODING", "TokenInfo"] +__all__ = [x for x in dir(token) if not x.startswith("_")] +__all__.extend(["COMMENT", "tokenize", "detect_encoding", "NL", "untokenize", + "ENCODING", "TokenInfo"]) del token COMMENT = N_TOKENS @@ -407,7 +407,7 @@ if encoding is not None: line = line.decode(encoding) - lnum = lnum + 1 + lnum += 1 pos, max = 0, len(line) if contstr: # continued string @@ -435,12 +435,17 @@ if not line: break column = 0 while pos < max: # measure leading whitespace - if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize - elif line[pos] == '\f': column = 0 - else: break - pos = pos + 1 - if pos == max: break + if line[pos] == ' ': + column += 1 + elif line[pos] == '\t': + column = (column//tabsize + 1)*tabsize + elif line[pos] == '\f': + column = 0 + else: + break + pos += 1 + if pos == max: + break if line[pos] in '#\r\n': # skip comments or blank lines if line[pos] == '#': @@ -516,13 +521,15 @@ elif initial == '\\': # continued stmt continued = 1 else: - if initial in '([{': parenlev = parenlev + 1 - elif initial in ')]}': parenlev = parenlev - 1 + if initial in '([{': + parenlev += 1 + elif initial in ')]}': + parenlev -= 1 yield TokenInfo(OP, token, spos, epos, line) else: yield TokenInfo(ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) - pos = pos + 1 + pos += 1 for indent in indents[1:]: # pop remaining indent levels yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') Modified: python/branches/release31-maint/Lib/xml/__init__.py ============================================================================== --- python/branches/release31-maint/Lib/xml/__init__.py (original) +++ python/branches/release31-maint/Lib/xml/__init__.py Fri Nov 13 03:29:35 2009 @@ -19,12 +19,6 @@ __all__ = ["dom", "parsers", "sax", "etree"] -# When being checked-out without options, this has the form -# "Revision: x.y " -# When exported using -kv, it is "x.y". -__version__ = "$Revision$".split()[-2:][0] - - _MINIMUM_XMLPLUS_VERSION = (0, 8, 4) Modified: python/branches/release31-maint/Misc/Porting ============================================================================== --- python/branches/release31-maint/Misc/Porting (original) +++ python/branches/release31-maint/Misc/Porting Fri Nov 13 03:29:35 2009 @@ -31,8 +31,7 @@ it out of the config.c file. Bang on it until you get a >>> prompt. (You may have to disable the -importing of "site.py" and "exceptions.py" by passing -X and -S -options. +importing of "site.py" by passing the -S options.) Then bang on it until it executes very simple Python statements. Modified: python/branches/release31-maint/Modules/mathmodule.c ============================================================================== --- python/branches/release31-maint/Modules/mathmodule.c (original) +++ python/branches/release31-maint/Modules/mathmodule.c Fri Nov 13 03:29:35 2009 @@ -374,7 +374,7 @@ "This is the smallest integral value >= x."); FUNC2(copysign, copysign, - "copysign(x,y)\n\nReturn x with the sign of y.") + "copysign(x, y)\n\nReturn x with the sign of y.") FUNC1(cos, cos, 0, "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, 1, @@ -406,8 +406,8 @@ "This is the largest integral value <= x."); FUNC1(log1p, log1p, 1, - "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n\ - The result is computed in a way which is accurate for x near zero.") + "log1p(x)\n\nReturn the natural logarithm of 1+x (base e).\n" + "The result is computed in a way which is accurate for x near zero.") FUNC1(sin, sin, 0, "sin(x)\n\nReturn the sine of x (measured in radians).") FUNC1(sinh, sinh, 1, @@ -636,7 +636,7 @@ #undef NUM_PARTIALS PyDoc_STRVAR(math_fsum_doc, -"sum(iterable)\n\n\ +"fsum(iterable)\n\n\ Return an accurate floating point sum of values in the iterable.\n\ Assumes IEEE-754 floating point arithmetic."); @@ -812,7 +812,8 @@ } PyDoc_STRVAR(math_ldexp_doc, -"ldexp(x, i) -> x * (2**i)"); +"ldexp(x, i)\n\n\ +Return x * (2**i)."); static PyObject * math_modf(PyObject *self, PyObject *arg) @@ -903,7 +904,8 @@ } PyDoc_STRVAR(math_log_doc, -"log(x[, base]) -> the logarithm of x to the given base.\n\ +"log(x[, base])\n\n\ +Return the logarithm of x to the given base.\n\ If the base not specified, returns the natural logarithm (base e) of x."); static PyObject * @@ -913,7 +915,7 @@ } PyDoc_STRVAR(math_log10_doc, -"log10(x) -> the base 10 logarithm of x."); +"log10(x)\n\nReturn the base 10 logarithm of x."); static PyObject * math_fmod(PyObject *self, PyObject *args) @@ -946,7 +948,7 @@ } PyDoc_STRVAR(math_fmod_doc, -"fmod(x,y)\n\nReturn fmod(x, y), according to platform C." +"fmod(x, y)\n\nReturn fmod(x, y), according to platform C." " x % y may differ."); static PyObject * @@ -988,7 +990,7 @@ } PyDoc_STRVAR(math_hypot_doc, -"hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y)."); +"hypot(x, y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y)."); /* pow can't use math_2, but needs its own wrapper: the problem is that an infinite result can arise either as a result of overflow @@ -1075,7 +1077,7 @@ } PyDoc_STRVAR(math_pow_doc, -"pow(x,y)\n\nReturn x**y (x to the power of y)."); +"pow(x, y)\n\nReturn x**y (x to the power of y)."); static const double degToRad = Py_MATH_PI / 180.0; static const double radToDeg = 180.0 / Py_MATH_PI; @@ -1090,7 +1092,8 @@ } PyDoc_STRVAR(math_degrees_doc, -"degrees(x) -> converts angle x from radians to degrees"); +"degrees(x)\n\n\ +Convert angle x from radians to degrees."); static PyObject * math_radians(PyObject *self, PyObject *arg) @@ -1102,7 +1105,8 @@ } PyDoc_STRVAR(math_radians_doc, -"radians(x) -> converts angle x from degrees to radians"); +"radians(x)\n\n\ +Convert angle x from degrees to radians."); static PyObject * math_isnan(PyObject *self, PyObject *arg) @@ -1114,8 +1118,8 @@ } PyDoc_STRVAR(math_isnan_doc, -"isnan(x) -> bool\n\ -Checks if float x is not a number (NaN)"); +"isnan(x) -> bool\n\n\ +Check if float x is not a number (NaN)."); static PyObject * math_isinf(PyObject *self, PyObject *arg) @@ -1127,8 +1131,8 @@ } PyDoc_STRVAR(math_isinf_doc, -"isinf(x) -> bool\n\ -Checks if float x is infinite (positive or negative)"); +"isinf(x) -> bool\n\n\ +Check if float x is infinite (positive or negative)."); static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, Modified: python/branches/release31-maint/Modules/operator.c ============================================================================== --- python/branches/release31-maint/Modules/operator.c (original) +++ python/branches/release31-maint/Modules/operator.c Fri Nov 13 03:29:35 2009 @@ -7,7 +7,7 @@ This module exports a set of functions implemented in C corresponding\n\ to the intrinsic operators of Python. For example, operator.add(x, y)\n\ is equivalent to the expression x+y. The function names are those\n\ -used for special class methods; variants without leading and trailing\n\ +used for special methods; variants without leading and trailing\n\ '__' are also provided for convenience."); #define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \ @@ -197,21 +197,21 @@ spam2(and_,__and__, "and_(a, b) -- Same as a & b.") spam2(xor,__xor__, "xor(a, b) -- Same as a ^ b.") spam2(or_,__or__, "or_(a, b) -- Same as a | b.") -spam2(iadd,__iadd__, "iadd(a, b) -- Same as a += b.") -spam2(isub,__isub__, "isub(a, b) -- Same as a -= b.") -spam2(imul,__imul__, "imul(a, b) -- Same as a *= b.") -spam2(ifloordiv,__ifloordiv__, "ifloordiv(a, b) -- Same as a //= b.") -spam2(itruediv,__itruediv__, "itruediv(a, b) -- Same as a /= b.") -spam2(imod,__imod__, "imod(a, b) -- Same as a %= b.") -spam2(ilshift,__ilshift__, "ilshift(a, b) -- Same as a <<= b.") -spam2(irshift,__irshift__, "irshift(a, b) -- Same as a >>= b.") -spam2(iand,__iand__, "iand(a, b) -- Same as a &= b.") -spam2(ixor,__ixor__, "ixor(a, b) -- Same as a ^= b.") -spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.") +spam2(iadd,__iadd__, "a = iadd(a, b) -- Same as a += b.") +spam2(isub,__isub__, "a = isub(a, b) -- Same as a -= b.") +spam2(imul,__imul__, "a = imul(a, b) -- Same as a *= b.") +spam2(ifloordiv,__ifloordiv__, "a = ifloordiv(a, b) -- Same as a //= b.") +spam2(itruediv,__itruediv__, "a = itruediv(a, b) -- Same as a /= b") +spam2(imod,__imod__, "a = imod(a, b) -- Same as a %= b.") +spam2(ilshift,__ilshift__, "a = ilshift(a, b) -- Same as a <<= b.") +spam2(irshift,__irshift__, "a = irshift(a, b) -- Same as a >>= b.") +spam2(iand,__iand__, "a = iand(a, b) -- Same as a &= b.") +spam2(ixor,__ixor__, "a = ixor(a, b) -- Same as a ^= b.") +spam2(ior,__ior__, "a = ior(a, b) -- Same as a |= b.") spam2(concat,__concat__, "concat(a, b) -- Same as a + b, for a and b sequences.") spam2(iconcat,__iconcat__, - "iconcat(a, b) -- Same as a += b, for a and b sequences.") + "a = iconcat(a, b) -- Same as a += b, for a and b sequences.") spam2(getitem,__getitem__, "getitem(a, b) -- Same as a[b].") spam2(setitem,__setitem__, @@ -219,7 +219,7 @@ spam2(delitem,__delitem__, "delitem(a, b) -- Same as del a[b].") spam2(pow,__pow__, "pow(a, b) -- Same as a ** b.") -spam2(ipow,__ipow__, "ipow(a, b) -- Same as a **= b.") +spam2(ipow,__ipow__, "a = ipow(a, b) -- Same as a **= b.") spam2(lt,__lt__, "lt(a, b) -- Same as aprop_doc); prop->prop_doc = get_doc; - } else { - /* Put __doc__ in dict of the subclass instance instead, - otherwise it gets shadowed by class's __doc__. */ - if (PyObject_SetAttrString(self, "__doc__", get_doc) != 0) - { - /* DECREF for props handled by _dealloc */ - Py_DECREF(get_doc); + } + else { + /* If this is a property subclass, put __doc__ + in dict of the subclass instance instead, + otherwise it gets shadowed by __doc__ in the + class's dict. */ + int err = PyObject_SetAttrString(self, "__doc__", get_doc); + Py_DECREF(get_doc); + if (err < 0) return -1; - } - Py_DECREF(get_doc); } prop->getter_doc = 1; - } else { + } + else if (PyErr_ExceptionMatches(PyExc_Exception)) { PyErr_Clear(); } + else { + return -1; + } } return 0; Modified: python/branches/release31-maint/Objects/listobject.c ============================================================================== --- python/branches/release31-maint/Objects/listobject.c (original) +++ python/branches/release31-maint/Objects/listobject.c Fri Nov 13 03:29:35 2009 @@ -183,9 +183,12 @@ return NULL; } if (i < 0 || i >= Py_SIZE(op)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } @@ -406,9 +409,12 @@ list_item(PyListObject *a, Py_ssize_t i) { if (i < 0 || i >= Py_SIZE(a)) { - if (indexerr == NULL) + if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); + if (indexerr == NULL) + return NULL; + } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } Modified: python/branches/release31-maint/Objects/moduleobject.c ============================================================================== --- python/branches/release31-maint/Objects/moduleobject.c (original) +++ python/branches/release31-maint/Objects/moduleobject.c Fri Nov 13 03:29:35 2009 @@ -312,7 +312,10 @@ if (m->md_def && m->md_def->m_free) m->md_def->m_free(m); if (m->md_dict != NULL) { - _PyModule_Clear((PyObject *)m); + /* If we are the only ones holding a reference, we can clear + the dictionary. */ + if (Py_REFCNT(m->md_dict) == 1) + _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } if (m->md_state != NULL) Modified: python/branches/release31-maint/Parser/tokenizer.c ============================================================================== --- python/branches/release31-maint/Parser/tokenizer.c (original) +++ python/branches/release31-maint/Parser/tokenizer.c Fri Nov 13 03:29:35 2009 @@ -195,20 +195,26 @@ int i; for (i = 0; i < 12; i++) { int c = s[i]; - if (c == '\0') break; - else if (c == '_') buf[i] = '-'; - else buf[i] = tolower(c); + if (c == '\0') + break; + else if (c == '_') + buf[i] = '-'; + else + buf[i] = tolower(c); } buf[i] = '\0'; if (strcmp(buf, "utf-8") == 0 || - strncmp(buf, "utf-8-", 6) == 0) return "utf-8"; + strncmp(buf, "utf-8-", 6) == 0) + return "utf-8"; else if (strcmp(buf, "latin-1") == 0 || strcmp(buf, "iso-8859-1") == 0 || strcmp(buf, "iso-latin-1") == 0 || strncmp(buf, "latin-1-", 8) == 0 || strncmp(buf, "iso-8859-1-", 11) == 0 || - strncmp(buf, "iso-latin-1-", 12) == 0) return "iso-8859-1"; - else return s; + strncmp(buf, "iso-latin-1-", 12) == 0) + return "iso-8859-1"; + else + return s; } /* Return the coding spec in S, or NULL if none is found. */ @@ -334,12 +340,18 @@ /* Disable support for UTF-16 BOMs until a decision is made whether this needs to be supported. */ } else if (ch == 0xFE) { - ch = get_char(tok); if (ch != 0xFF) goto NON_BOM; - if (!set_readline(tok, "utf-16-be")) return 0; + ch = get_char(tok); + if (ch != 0xFF) + goto NON_BOM; + if (!set_readline(tok, "utf-16-be")) + return 0; tok->decoding_state = STATE_NORMAL; } else if (ch == 0xFF) { - ch = get_char(tok); if (ch != 0xFE) goto NON_BOM; - if (!set_readline(tok, "utf-16-le")) return 0; + ch = get_char(tok); + if (ch != 0xFE) + goto NON_BOM; + if (!set_readline(tok, "utf-16-le")) + return 0; tok->decoding_state = STATE_NORMAL; #endif } else { @@ -980,7 +992,7 @@ { if (c != EOF) { if (--tok->cur < tok->buf) - Py_FatalError("tok_backup: begin of buffer"); + Py_FatalError("tok_backup: beginning of buffer"); if (*tok->cur != c) *tok->cur = c; } From python-checkins at python.org Fri Nov 13 03:43:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 02:43:40 -0000 Subject: [Python-checkins] r76237 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Fri Nov 13 03:43:40 2009 New Revision: 76237 Log: Blocked revisions 75407-75413,75415,75417,75419-75421 via svnmerge ........ r75407 | antoine.pitrou | 2009-10-14 12:30:52 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in the aifc module ........ r75408 | antoine.pitrou | 2009-10-14 12:34:31 -0500 (Wed, 14 Oct 2009) | 3 lines Fix a test_atexit failure when run with -3 ........ r75409 | antoine.pitrou | 2009-10-14 13:01:33 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in bsddb ........ r75410 | antoine.pitrou | 2009-10-14 13:09:45 -0500 (Wed, 14 Oct 2009) | 3 lines Silence a py3k warning claiming to affect Lib/calendar.py ........ r75411 | antoine.pitrou | 2009-10-14 13:12:54 -0500 (Wed, 14 Oct 2009) | 3 lines Fix a py3k warning in the StringIO module (exhibited in test_codecencodings_cn) ........ r75412 | antoine.pitrou | 2009-10-14 13:27:32 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in the socket module ........ r75413 | antoine.pitrou | 2009-10-14 13:31:05 -0500 (Wed, 14 Oct 2009) | 3 lines Fix a py3k warning in the sndhdr module (found with test_email) ........ r75415 | antoine.pitrou | 2009-10-14 13:39:46 -0500 (Wed, 14 Oct 2009) | 3 lines Silence some py3k warnings claiming to affect _pyio ........ r75417 | antoine.pitrou | 2009-10-14 13:47:13 -0500 (Wed, 14 Oct 2009) | 3 lines Fix failures in test_profilehooks when run with -3 ........ r75419 | antoine.pitrou | 2009-10-14 13:56:11 -0500 (Wed, 14 Oct 2009) | 3 lines Silence py3k warning claiming to affect the random module ........ r75420 | antoine.pitrou | 2009-10-14 14:04:48 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in httplib ........ r75421 | antoine.pitrou | 2009-10-14 14:09:48 -0500 (Wed, 14 Oct 2009) | 3 lines Fix py3k warnings in the uuid module ........ Modified: python/branches/py3k/ (props changed) From ncoghlan at gmail.com Fri Nov 13 10:57:48 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Fri, 13 Nov 2009 19:57:48 +1000 Subject: [Python-checkins] r76233 - python/branches/py3k/Lib/importlib/_bootstrap.py In-Reply-To: References: <4afcac97.051abc0a.5fd0.ffff9e28SMTPIN_ADDED@mx.google.com> Message-ID: <4AFD2D9C.6000700@gmail.com> Brett Cannon wrote: > On Thu, Nov 12, 2009 at 16:47, benjamin.peterson > wrote: >> Author: benjamin.peterson >> Date: Fri Nov 13 01:45:32 2009 >> New Revision: 76233 >> >> Log: >> no need to translate newlines in python code anymore > > Sweet! Thanks for this, Benjamin! I always hated having this hack in > the code since I knew it was a nasty performance hit. I was planning > on trying to solve it at some point. Glad you beat me to it. =) Whereas runpy.run_module was probably just plain broken in some cases... (most of the time it would have been OK, as pkgutil's PEP 302 style importer for the file system uses rU mode to read the source files, but runpy itself certainly didn't have anything like the importlib workaround) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From nnorwitz at gmail.com Fri Nov 13 11:54:19 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 13 Nov 2009 05:54:19 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091113105419.GA27827@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [-81, 420, 0] references, sum=339 Less important issues: ---------------------- test_bz2 leaked [0, 91, -91] references, sum=0 From python-checkins at python.org Fri Nov 13 17:10:13 2009 From: python-checkins at python.org (kristjan.jonsson) Date: Fri, 13 Nov 2009 16:10:13 -0000 Subject: [Python-checkins] r76238 - in python/branches/py3k: Doc/library/unittest.rst Lib/test/test_unittest.py Lib/unittest/case.py Message-ID: Author: kristjan.jonsson Date: Fri Nov 13 17:10:13 2009 New Revision: 76238 Log: Merged revisions 74556 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r74556 | kristjan.jonsson | 2009-08-27 22:20:21 +0000 (fim., 27 ?g?. 2009) | 2 lines issue 6275 Add an "exc_value" attribute to the _AssertRaisesContext context manager in the unittest package. This allows further tests on the exception that was raised after the context manager exits. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Lib/test/test_unittest.py python/branches/py3k/Lib/unittest/case.py Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Fri Nov 13 17:10:13 2009 @@ -891,12 +891,19 @@ with self.failUnlessRaises(some_error_class): do_something() + The context manager will store the caught exception object in its + :attr:`exc_value` attribute. This can be useful if the intention + is to perform additional checks on the exception raised. + .. versionchanged:: 3.1 Added the ability to use :meth:`assertRaises` as a context manager. .. deprecated:: 3.1 :meth:`failUnlessRaises`. + .. versionchanged:: 3.1 + Added the :attr:`exc_value` attribute. + .. method:: assertRaisesRegexp(exception, regexp[, callable, ...]) Modified: python/branches/py3k/Lib/test/test_unittest.py ============================================================================== --- python/branches/py3k/Lib/test/test_unittest.py (original) +++ python/branches/py3k/Lib/test/test_unittest.py Fri Nov 13 17:10:13 2009 @@ -2847,6 +2847,21 @@ self.assertRaisesRegexp, Exception, re.compile('^Expected$'), Stub) + def testAssertRaisesExcValue(self): + class ExceptionMock(Exception): + pass + + def Stub(foo): + raise ExceptionMock(foo) + v = "particular value" + + ctx = self.assertRaises(ExceptionMock) + with ctx: + Stub(v) + e = ctx.exc_value + self.assertTrue(isinstance(e, ExceptionMock)) + self.assertEqual(e.args[0], v) + def testSynonymAssertMethodNames(self): """Test undocumented method name synonyms. Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Fri Nov 13 17:10:13 2009 @@ -116,6 +116,9 @@ if not issubclass(exc_type, self.expected): # let unexpected exceptions pass through return False + #store exception, without traceback, for later retrieval + self.exc_value = exc_value + self.exc_value.with_traceback(None) if self.expected_regex is None: return True From python-checkins at python.org Fri Nov 13 17:15:57 2009 From: python-checkins at python.org (kristjan.jonsson) Date: Fri, 13 Nov 2009 16:15:57 -0000 Subject: [Python-checkins] r76239 - python/branches/py3k/Doc/library/unittest.rst Message-ID: Author: kristjan.jonsson Date: Fri Nov 13 17:15:57 2009 New Revision: 76239 Log: Fix incorrect "versionchanged" version number from revision 76238 Modified: python/branches/py3k/Doc/library/unittest.rst Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Fri Nov 13 17:15:57 2009 @@ -901,7 +901,7 @@ .. deprecated:: 3.1 :meth:`failUnlessRaises`. - .. versionchanged:: 3.1 + .. versionchanged:: 3.2 Added the :attr:`exc_value` attribute. From python-checkins at python.org Fri Nov 13 17:29:04 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 16:29:04 -0000 Subject: [Python-checkins] r76240 - in python/branches/py3k: Lib/test/support.py Lib/test/test_importhooks.py Lib/test/test_pkg.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 13 17:29:04 2009 New Revision: 76240 Log: Issue #6551: test_zipimport could import and then destroy some modules of the encodings package, which would make other tests fail further down the road because the internally cached encoders and decoders would point to empty global variables. Modified: python/branches/py3k/Lib/test/support.py python/branches/py3k/Lib/test/test_importhooks.py python/branches/py3k/Lib/test/test_pkg.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/support.py ============================================================================== --- python/branches/py3k/Lib/test/support.py (original) +++ python/branches/py3k/Lib/test/support.py Fri Nov 13 17:29:04 2009 @@ -951,6 +951,23 @@ (module.__name__, t)) return f, t + +#======================================================================= +# Support for saving and restoring the imported modules. + +def modules_setup(): + return sys.modules.copy(), + +def modules_cleanup(oldmodules): + # Encoders/decoders are registered permanently within the internal + # codec cache. If we destroy the corresponding modules their + # globals will be set to None which will trip up the cached functions. + encodings = [(k, v) for k, v in sys.modules.items() + if k.startswith('encodings.')] + sys.modules.clear() + sys.modules.update(encodings) + sys.modules.update(oldmodules) + #======================================================================= # Threading support to prevent reporting refleaks when running regrtest.py -R Modified: python/branches/py3k/Lib/test/test_importhooks.py ============================================================================== --- python/branches/py3k/Lib/test/test_importhooks.py (original) +++ python/branches/py3k/Lib/test/test_importhooks.py Fri Nov 13 17:29:04 2009 @@ -143,15 +143,14 @@ self.meta_path = sys.meta_path[:] self.path_hooks = sys.path_hooks[:] sys.path_importer_cache.clear() - self.modules_before = sys.modules.copy() + self.modules_before = support.modules_setup() def tearDown(self): sys.path[:] = self.path sys.meta_path[:] = self.meta_path sys.path_hooks[:] = self.path_hooks sys.path_importer_cache.clear() - sys.modules.clear() - sys.modules.update(self.modules_before) + support.modules_cleanup(*self.modules_before) class ImportHooksTestCase(ImportHooksBaseTestCase): Modified: python/branches/py3k/Lib/test/test_pkg.py ============================================================================== --- python/branches/py3k/Lib/test/test_pkg.py (original) +++ python/branches/py3k/Lib/test/test_pkg.py Fri Nov 13 17:29:04 2009 @@ -48,13 +48,11 @@ self.root = None self.pkgname = None self.syspath = list(sys.path) - self.sysmodules = sys.modules.copy() + self.modules_before = support.modules_setup() def tearDown(self): sys.path[:] = self.syspath - sys.modules.clear() - sys.modules.update(self.sysmodules) - del self.sysmodules + support.modules_cleanup(*self.modules_before) cleanout(self.root) # delete all modules concerning the tested hiearchy Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Nov 13 17:29:04 2009 @@ -373,6 +373,11 @@ Tests ----- +- Issue #6551: test_zipimport could import and then destroy some modules of + the encodings package, which would make other tests fail further down + the road because the internally cached encoders and decoders would point + to empty global variables. + - Issue #7295: Do not use a hardcoded file name in test_tarfile. - Issue #7270: Add some dedicated unit tests for multi-thread synchronization From python-checkins at python.org Fri Nov 13 17:31:51 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 16:31:51 -0000 Subject: [Python-checkins] r76241 - in python/branches/release31-maint: Lib/test/support.py Lib/test/test_importhooks.py Lib/test/test_pkg.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 13 17:31:51 2009 New Revision: 76241 Log: Merged revisions 76240 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76240 | antoine.pitrou | 2009-11-13 17:29:04 +0100 (ven., 13 nov. 2009) | 6 lines Issue #6551: test_zipimport could import and then destroy some modules of the encodings package, which would make other tests fail further down the road because the internally cached encoders and decoders would point to empty global variables. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/support.py python/branches/release31-maint/Lib/test/test_importhooks.py python/branches/release31-maint/Lib/test/test_pkg.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/test/support.py ============================================================================== --- python/branches/release31-maint/Lib/test/support.py (original) +++ python/branches/release31-maint/Lib/test/support.py Fri Nov 13 17:31:51 2009 @@ -919,6 +919,23 @@ (module.__name__, t)) return f, t + +#======================================================================= +# Support for saving and restoring the imported modules. + +def modules_setup(): + return sys.modules.copy(), + +def modules_cleanup(oldmodules): + # Encoders/decoders are registered permanently within the internal + # codec cache. If we destroy the corresponding modules their + # globals will be set to None which will trip up the cached functions. + encodings = [(k, v) for k, v in sys.modules.items() + if k.startswith('encodings.')] + sys.modules.clear() + sys.modules.update(encodings) + sys.modules.update(oldmodules) + #======================================================================= # Threading support to prevent reporting refleaks when running regrtest.py -R Modified: python/branches/release31-maint/Lib/test/test_importhooks.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_importhooks.py (original) +++ python/branches/release31-maint/Lib/test/test_importhooks.py Fri Nov 13 17:31:51 2009 @@ -143,15 +143,14 @@ self.meta_path = sys.meta_path[:] self.path_hooks = sys.path_hooks[:] sys.path_importer_cache.clear() - self.modules_before = sys.modules.copy() + self.modules_before = support.modules_setup() def tearDown(self): sys.path[:] = self.path sys.meta_path[:] = self.meta_path sys.path_hooks[:] = self.path_hooks sys.path_importer_cache.clear() - sys.modules.clear() - sys.modules.update(self.modules_before) + support.modules_cleanup(*self.modules_before) class ImportHooksTestCase(ImportHooksBaseTestCase): Modified: python/branches/release31-maint/Lib/test/test_pkg.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_pkg.py (original) +++ python/branches/release31-maint/Lib/test/test_pkg.py Fri Nov 13 17:31:51 2009 @@ -48,13 +48,11 @@ self.root = None self.pkgname = None self.syspath = list(sys.path) - self.sysmodules = sys.modules.copy() + self.modules_before = support.modules_setup() def tearDown(self): sys.path[:] = self.syspath - sys.modules.clear() - sys.modules.update(self.sysmodules) - del self.sysmodules + support.modules_cleanup(*self.modules_before) cleanout(self.root) # delete all modules concerning the tested hiearchy Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Nov 13 17:31:51 2009 @@ -144,6 +144,11 @@ Tests ----- +- Issue #6551: test_zipimport could import and then destroy some modules of + the encodings package, which would make other tests fail further down + the road because the internally cached encoders and decoders would point + to empty global variables. + - Issue #7295: Do not use a hardcoded file name in test_tarfile. - Issue #7270: Add some dedicated unit tests for multi-thread synchronization From g.brandl at gmx.net Fri Nov 13 22:20:53 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Fri, 13 Nov 2009 22:20:53 +0100 Subject: [Python-checkins] r76230 - in python/trunk: Doc/library/functions.rst Lib/test/test_codeop.py Lib/test/test_compile.py Lib/test/test_parser.py Misc/NEWS Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h In-Reply-To: <678.629466756497$1258069606@news.gmane.org> References: <678.629466756497$1258069606@news.gmane.org> Message-ID: benjamin.peterson schrieb: > Modified: python/trunk/Doc/library/functions.rst > ============================================================================== > --- python/trunk/Doc/library/functions.rst (original) > +++ python/trunk/Doc/library/functions.rst Fri Nov 13 00:39:44 2009 > @@ -173,11 +173,10 @@ > > .. note:: > > - When compiling a string with multi-line statements, line endings must be > - represented by a single newline character (``'\n'``), and the input must > - be terminated by at least one newline character. If line endings are > - represented by ``'\r\n'``, use :meth:`str.replace` to change them into > - ``'\n'``. > + When compiling a string with multi-line statements in ``'single'`` or > + ``'eval'`` mode, input must be terminated by at least one newline > + character. This is to facilitate detection of incomplete and complete > + statements in the :mod:`code` module. Multi-line statements in "eval" mode? Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out. From python-checkins at python.org Fri Nov 13 23:09:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 22:09:10 -0000 Subject: [Python-checkins] r76242 - python/branches/py3k/Lib/unittest/case.py Message-ID: Author: benjamin.peterson Date: Fri Nov 13 23:09:10 2009 New Revision: 76242 Log: use with_traceback correctly Modified: python/branches/py3k/Lib/unittest/case.py Modified: python/branches/py3k/Lib/unittest/case.py ============================================================================== --- python/branches/py3k/Lib/unittest/case.py (original) +++ python/branches/py3k/Lib/unittest/case.py Fri Nov 13 23:09:10 2009 @@ -117,8 +117,7 @@ # let unexpected exceptions pass through return False #store exception, without traceback, for later retrieval - self.exc_value = exc_value - self.exc_value.with_traceback(None) + self.exc_value = exc_value.with_traceback(None) if self.expected_regex is None: return True From python-checkins at python.org Fri Nov 13 23:17:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 22:17:18 -0000 Subject: [Python-checkins] r76243 - python/trunk/Doc/library/functions.rst Message-ID: Author: benjamin.peterson Date: Fri Nov 13 23:17:17 2009 New Revision: 76243 Log: never mind about eval mode in this case Modified: python/trunk/Doc/library/functions.rst Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Fri Nov 13 23:17:17 2009 @@ -173,10 +173,10 @@ .. note:: - When compiling a string with multi-line statements in ``'single'`` or - ``'eval'`` mode, input must be terminated by at least one newline - character. This is to facilitate detection of incomplete and complete - statements in the :mod:`code` module. + When compiling a string with multi-line statements in ``'single'``, input + must be terminated by at least one newline character. This is to + facilitate detection of incomplete and complete statements in the + :mod:`code` module. .. versionchanged:: 2.3 The *flags* and *dont_inherit* arguments were added. From python-checkins at python.org Fri Nov 13 23:19:19 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 22:19:19 -0000 Subject: [Python-checkins] r76244 - in python/branches/py3k/Lib/test: test_sys.py test_threading.py Message-ID: Author: antoine.pitrou Date: Fri Nov 13 23:19:19 2009 New Revision: 76244 Log: Silence getcheckinterval()-related warnings in the test suite Modified: python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Lib/test/test_threading.py Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Fri Nov 13 23:19:19 2009 @@ -4,6 +4,7 @@ import struct import subprocess import textwrap +import warnings # count the number of test runs, used to create unique # strings to intern in test_intern() @@ -148,11 +149,13 @@ # testing sys.setprofile() is done in test_profile.py def test_setcheckinterval(self): - self.assertRaises(TypeError, sys.setcheckinterval) - orig = sys.getcheckinterval() - for n in 0, 100, 120, orig: # orig last to restore starting state - sys.setcheckinterval(n) - self.assertEquals(sys.getcheckinterval(), n) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + self.assertRaises(TypeError, sys.setcheckinterval) + orig = sys.getcheckinterval() + for n in 0, 100, 120, orig: # orig last to restore starting state + sys.setcheckinterval(n) + self.assertEquals(sys.getcheckinterval(), n) def test_switchinterval(self): self.assertRaises(TypeError, sys.setswitchinterval) Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Fri Nov 13 23:19:19 2009 @@ -342,12 +342,10 @@ # Try hard to trigger #1703448: a thread is still returned in # threading.enumerate() after it has been join()ed. enum = threading.enumerate - old_interval = sys.getcheckinterval() + old_interval = sys.getswitchinterval() try: for i in range(1, 100): - # Try a couple times at each thread-switching interval - # to get more interleavings. - sys.setcheckinterval(i // 5) + sys.setswitchinterval(i * 0.0002) t = threading.Thread(target=lambda: None) t.start() t.join() @@ -355,7 +353,7 @@ self.assertFalse(t in l, "#1703448 triggered after %d trials: %s" % (i, l)) finally: - sys.setcheckinterval(old_interval) + sys.setswitchinterval(old_interval) def test_no_refcycle_through_target(self): class RunSelfFunction(object): From ncoghlan at gmail.com Fri Nov 13 23:24:29 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sat, 14 Nov 2009 08:24:29 +1000 Subject: [Python-checkins] r76230 - in python/trunk: Doc/library/functions.rst Lib/test/test_codeop.py Lib/test/test_compile.py Lib/test/test_parser.py Misc/NEWS Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h In-Reply-To: References: <678.629466756497$1258069606@news.gmane.org> Message-ID: <4AFDDC9D.1080605@gmail.com> Georg Brandl wrote: > benjamin.peterson schrieb: > >> Modified: python/trunk/Doc/library/functions.rst >> ============================================================================== >> --- python/trunk/Doc/library/functions.rst (original) >> +++ python/trunk/Doc/library/functions.rst Fri Nov 13 00:39:44 2009 >> @@ -173,11 +173,10 @@ >> >> .. note:: >> >> - When compiling a string with multi-line statements, line endings must be >> - represented by a single newline character (``'\n'``), and the input must >> - be terminated by at least one newline character. If line endings are >> - represented by ``'\r\n'``, use :meth:`str.replace` to change them into >> - ``'\n'``. >> + When compiling a string with multi-line statements in ``'single'`` or >> + ``'eval'`` mode, input must be terminated by at least one newline >> + character. This is to facilitate detection of incomplete and complete >> + statements in the :mod:`code` module. > > Multi-line statements in "eval" mode? You can do that with line continuations and bracket matching. >>>code = compile("sys.stdout.write(str(\n1\n+\n1)+'\\n')\n", "", "eval") >>> import sys >>> exec code 2 Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From ncoghlan at gmail.com Fri Nov 13 23:25:29 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sat, 14 Nov 2009 08:25:29 +1000 Subject: [Python-checkins] r76243 - python/trunk/Doc/library/functions.rst In-Reply-To: <4afddb35.071abc0a.5e91.fffff73eSMTPIN_ADDED@mx.google.com> References: <4afddb35.071abc0a.5e91.fffff73eSMTPIN_ADDED@mx.google.com> Message-ID: <4AFDDCD9.5070400@gmail.com> benjamin.peterson wrote: > Author: benjamin.peterson > Date: Fri Nov 13 23:17:17 2009 > New Revision: 76243 > > Log: > never mind about eval mode in this case You were right the first time :) (see my response to Georg) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From python-checkins at python.org Fri Nov 13 23:31:18 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 22:31:18 -0000 Subject: [Python-checkins] r76245 - in python/trunk: Lib/multiprocessing/connection.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 13 23:31:18 2009 New Revision: 76245 Log: Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for local connections. Modified: python/trunk/Lib/multiprocessing/connection.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/multiprocessing/connection.py ============================================================================== --- python/trunk/Lib/multiprocessing/connection.py (original) +++ python/trunk/Lib/multiprocessing/connection.py Fri Nov 13 23:31:18 2009 @@ -27,6 +27,8 @@ # BUFSIZE = 8192 +# A very generous timeout when it comes to local connections... +CONNECTION_TIMEOUT = 20. _mmap_counter = itertools.count() @@ -41,6 +43,13 @@ default_family = 'AF_PIPE' families += ['AF_PIPE'] + +def _init_timeout(timeout=CONNECTION_TIMEOUT): + return time.time() + timeout + +def _check_timeout(t): + return time.time() > t + # # # @@ -247,12 +256,13 @@ ''' family = address_type(address) s = socket.socket( getattr(socket, family) ) + t = _init_timeout() while 1: try: s.connect(address) except socket.error, e: - if e.args[0] != errno.ECONNREFUSED: # connection refused + if e.args[0] != errno.ECONNREFUSED or _check_timeout(t): debug('failed to connect to address %s', address) raise time.sleep(0.01) @@ -322,6 +332,7 @@ ''' Return a connection object connected to the pipe given by `address` ''' + t = _init_timeout() while 1: try: win32.WaitNamedPipe(address, 1000) @@ -331,7 +342,7 @@ ) except WindowsError, e: if e.args[0] not in (win32.ERROR_SEM_TIMEOUT, - win32.ERROR_PIPE_BUSY): + win32.ERROR_PIPE_BUSY) or _check_timeout(t): raise else: break Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 13 23:31:18 2009 @@ -429,6 +429,11 @@ Library ------- +- Issue #7318: multiprocessing now uses a timeout when it fails to establish + a connection with another process, rather than looping endlessly. The + default timeout is 20 seconds, which should be amply sufficient for + local connections. + - Issue #7197: Allow unittest.TextTestRunner objects to be pickled and unpickled. This fixes crashes under Windows when trying to run test_multiprocessing in verbose mode. From python-checkins at python.org Fri Nov 13 23:33:27 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 22:33:27 -0000 Subject: [Python-checkins] r76246 - in python/branches/release26-maint: Lib/multiprocessing/connection.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 13 23:33:27 2009 New Revision: 76246 Log: Merged revisions 76245 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76245 | antoine.pitrou | 2009-11-13 23:31:18 +0100 (ven., 13 nov. 2009) | 6 lines Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for local connections. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/multiprocessing/connection.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/multiprocessing/connection.py ============================================================================== --- python/branches/release26-maint/Lib/multiprocessing/connection.py (original) +++ python/branches/release26-maint/Lib/multiprocessing/connection.py Fri Nov 13 23:33:27 2009 @@ -27,6 +27,8 @@ # BUFSIZE = 8192 +# A very generous timeout when it comes to local connections... +CONNECTION_TIMEOUT = 20. _mmap_counter = itertools.count() @@ -41,6 +43,13 @@ default_family = 'AF_PIPE' families += ['AF_PIPE'] + +def _init_timeout(timeout=CONNECTION_TIMEOUT): + return time.time() + timeout + +def _check_timeout(t): + return time.time() > t + # # # @@ -247,12 +256,13 @@ ''' family = address_type(address) s = socket.socket( getattr(socket, family) ) + t = _init_timeout() while 1: try: s.connect(address) except socket.error, e: - if e.args[0] != errno.ECONNREFUSED: # connection refused + if e.args[0] != errno.ECONNREFUSED or _check_timeout(t): debug('failed to connect to address %s', address) raise time.sleep(0.01) @@ -322,6 +332,7 @@ ''' Return a connection object connected to the pipe given by `address` ''' + t = _init_timeout() while 1: try: win32.WaitNamedPipe(address, 1000) @@ -331,7 +342,7 @@ ) except WindowsError, e: if e.args[0] not in (win32.ERROR_SEM_TIMEOUT, - win32.ERROR_PIPE_BUSY): + win32.ERROR_PIPE_BUSY) or _check_timeout(t): raise else: break Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Nov 13 23:33:27 2009 @@ -26,6 +26,11 @@ Library ------- +- Issue #7318: multiprocessing now uses a timeout when it fails to establish + a connection with another process, rather than looping endlessly. The + default timeout is 20 seconds, which should be amply sufficient for + local connections. + - Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `thread.start_new_thread()`. From python-checkins at python.org Fri Nov 13 23:35:18 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 22:35:18 -0000 Subject: [Python-checkins] r76247 - in python/branches/py3k: Lib/multiprocessing/connection.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 13 23:35:18 2009 New Revision: 76247 Log: Merged revisions 76245 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76245 | antoine.pitrou | 2009-11-13 23:31:18 +0100 (ven., 13 nov. 2009) | 6 lines Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for local connections. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/multiprocessing/connection.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/multiprocessing/connection.py ============================================================================== --- python/branches/py3k/Lib/multiprocessing/connection.py (original) +++ python/branches/py3k/Lib/multiprocessing/connection.py Fri Nov 13 23:35:18 2009 @@ -27,6 +27,8 @@ # BUFSIZE = 8192 +# A very generous timeout when it comes to local connections... +CONNECTION_TIMEOUT = 20. _mmap_counter = itertools.count() @@ -41,6 +43,13 @@ default_family = 'AF_PIPE' families += ['AF_PIPE'] + +def _init_timeout(timeout=CONNECTION_TIMEOUT): + return time.time() + timeout + +def _check_timeout(t): + return time.time() > t + # # # @@ -247,12 +256,13 @@ ''' family = address_type(address) s = socket.socket( getattr(socket, family) ) + t = _init_timeout() while 1: try: s.connect(address) except socket.error as e: - if e.args[0] != errno.ECONNREFUSED: # connection refused + if e.args[0] != errno.ECONNREFUSED or _check_timeout(t): debug('failed to connect to address %s', address) raise time.sleep(0.01) @@ -322,6 +332,7 @@ ''' Return a connection object connected to the pipe given by `address` ''' + t = _init_timeout() while 1: try: win32.WaitNamedPipe(address, 1000) @@ -331,7 +342,7 @@ ) except WindowsError as e: if e.args[0] not in (win32.ERROR_SEM_TIMEOUT, - win32.ERROR_PIPE_BUSY): + win32.ERROR_PIPE_BUSY) or _check_timeout(t): raise else: break Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Nov 13 23:35:18 2009 @@ -123,6 +123,11 @@ Library ------- +- Issue #7318: multiprocessing now uses a timeout when it fails to establish + a connection with another process, rather than looping endlessly. The + default timeout is 20 seconds, which should be amply sufficient for + local connections. + - Issue #7197: Allow unittest.TextTestRunner objects to be pickled and unpickled. This fixes crashes under Windows when trying to run test_multiprocessing in verbose mode. From python-checkins at python.org Fri Nov 13 23:39:40 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 22:39:40 -0000 Subject: [Python-checkins] r76248 - in python/branches/release31-maint: Lib/multiprocessing/connection.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 13 23:39:40 2009 New Revision: 76248 Log: Merged revisions 76247 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76247 | antoine.pitrou | 2009-11-13 23:35:18 +0100 (ven., 13 nov. 2009) | 12 lines Merged revisions 76245 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76245 | antoine.pitrou | 2009-11-13 23:31:18 +0100 (ven., 13 nov. 2009) | 6 lines Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for local connections. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/multiprocessing/connection.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/multiprocessing/connection.py ============================================================================== --- python/branches/release31-maint/Lib/multiprocessing/connection.py (original) +++ python/branches/release31-maint/Lib/multiprocessing/connection.py Fri Nov 13 23:39:40 2009 @@ -27,6 +27,8 @@ # BUFSIZE = 8192 +# A very generous timeout when it comes to local connections... +CONNECTION_TIMEOUT = 20. _mmap_counter = itertools.count() @@ -41,6 +43,13 @@ default_family = 'AF_PIPE' families += ['AF_PIPE'] + +def _init_timeout(timeout=CONNECTION_TIMEOUT): + return time.time() + timeout + +def _check_timeout(t): + return time.time() > t + # # # @@ -247,12 +256,13 @@ ''' family = address_type(address) s = socket.socket( getattr(socket, family) ) + t = _init_timeout() while 1: try: s.connect(address) except socket.error as e: - if e.args[0] != errno.ECONNREFUSED: # connection refused + if e.args[0] != errno.ECONNREFUSED or _check_timeout(t): debug('failed to connect to address %s', address) raise time.sleep(0.01) @@ -322,6 +332,7 @@ ''' Return a connection object connected to the pipe given by `address` ''' + t = _init_timeout() while 1: try: win32.WaitNamedPipe(address, 1000) @@ -331,7 +342,7 @@ ) except WindowsError as e: if e.args[0] not in (win32.ERROR_SEM_TIMEOUT, - win32.ERROR_PIPE_BUSY): + win32.ERROR_PIPE_BUSY) or _check_timeout(t): raise else: break Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Fri Nov 13 23:39:40 2009 @@ -40,6 +40,11 @@ Library ------- +- Issue #7318: multiprocessing now uses a timeout when it fails to establish + a connection with another process, rather than looping endlessly. The + default timeout is 20 seconds, which should be amply sufficient for + local connections. + - Issue #7282: Fix a memory leak when an RLock was used in a thread other than those started through `threading.Thread` (for example, using `_thread.start_new_thread()`). From benjamin at python.org Fri Nov 13 23:54:57 2009 From: benjamin at python.org (Benjamin Peterson) Date: Fri, 13 Nov 2009 16:54:57 -0600 Subject: [Python-checkins] r76230 - in python/trunk: Doc/library/functions.rst Lib/test/test_codeop.py Lib/test/test_compile.py Lib/test/test_parser.py Misc/NEWS Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h In-Reply-To: <4AFDDC9D.1080605@gmail.com> References: <678.629466756497$1258069606@news.gmane.org> <4AFDDC9D.1080605@gmail.com> Message-ID: <1afaf6160911131454v21f6de59mcda62f778e3a676c@mail.gmail.com> 2009/11/13 Nick Coghlan : > You can do that with line continuations and bracket matching. > >>>>code = compile("sys.stdout.write(str(\n1\n+\n1)+'\\n')\n", > "", "eval") >>>> import sys >>>> exec code > 2 Thank you! I knew there was some reason, but I couldn't remember it. :) -- Regards, Benjamin From python-checkins at python.org Fri Nov 13 23:56:00 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 22:56:00 -0000 Subject: [Python-checkins] r76249 - python/trunk/Doc/library/functions.rst Message-ID: Author: benjamin.peterson Date: Fri Nov 13 23:56:00 2009 New Revision: 76249 Log: revert r76243; I was right, actually :) Modified: python/trunk/Doc/library/functions.rst Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Fri Nov 13 23:56:00 2009 @@ -173,10 +173,10 @@ .. note:: - When compiling a string with multi-line statements in ``'single'``, input - must be terminated by at least one newline character. This is to - facilitate detection of incomplete and complete statements in the - :mod:`code` module. + When compiling a string with multi-line statements in ``'single'`` or + ``'eval'`` mode, input must be terminated by at least one newline + character. This is to facilitate detection of incomplete and complete + statements in the :mod:`code` module. .. versionchanged:: 2.3 The *flags* and *dont_inherit* arguments were added. From python-checkins at python.org Fri Nov 13 23:56:49 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 22:56:49 -0000 Subject: [Python-checkins] r76250 - in sandbox/trunk/2to3/lib2to3: pgen2/tokenize.py tests/data/bom.py tests/test_parser.py tests/test_refactor.py Message-ID: Author: benjamin.peterson Date: Fri Nov 13 23:56:48 2009 New Revision: 76250 Log: fix handling of a utf-8 bom #7313 Added: sandbox/trunk/2to3/lib2to3/tests/data/bom.py (contents, props changed) Modified: sandbox/trunk/2to3/lib2to3/pgen2/tokenize.py sandbox/trunk/2to3/lib2to3/tests/test_parser.py sandbox/trunk/2to3/lib2to3/tests/test_refactor.py Modified: sandbox/trunk/2to3/lib2to3/pgen2/tokenize.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/pgen2/tokenize.py (original) +++ sandbox/trunk/2to3/lib2to3/pgen2/tokenize.py Fri Nov 13 23:56:48 2009 @@ -281,9 +281,13 @@ # This behaviour mimics the Python interpreter raise SyntaxError("unknown encoding: " + encoding) - if bom_found and codec.name != 'utf-8': - # This behaviour mimics the Python interpreter - raise SyntaxError('encoding problem: utf-8') + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + raise SyntaxError('encoding problem: utf-8') + else: + # Allow it to be properly encoded and decoded. + encoding = 'utf-8-sig' return encoding first = read_or_stop() Added: sandbox/trunk/2to3/lib2to3/tests/data/bom.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/lib2to3/tests/data/bom.py Fri Nov 13 23:56:48 2009 @@ -0,0 +1,3 @@ +?# coding: utf-8 +print "BOM BOOM!" + Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_parser.py Fri Nov 13 23:56:48 2009 @@ -161,6 +161,7 @@ tree = driver.parse_string(source) new = unicode(tree) if diff(filepath, new, encoding): + import pdb; pdb.set_trace() self.fail("Idempotency failed: %s" % filepath) def test_extended_unpacking(self): Modified: sandbox/trunk/2to3/lib2to3/tests/test_refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_refactor.py Fri Nov 13 23:56:48 2009 @@ -4,6 +4,7 @@ import sys import os +import codecs import operator import StringIO import tempfile @@ -177,10 +178,12 @@ try: rt.refactor_file(test_file, True) - self.assertNotEqual(old_contents, read_file()) + new_contents = read_file() + self.assertNotEqual(old_contents, new_contents) finally: with open(test_file, "wb") as fp: fp.write(old_contents) + return new_contents def test_refactor_file(self): test_file = os.path.join(FIXER_DIR, "parrot_example.py") @@ -221,6 +224,11 @@ fn = os.path.join(TEST_DATA_DIR, "different_encoding.py") self.check_file_refactoring(fn) + def test_bom(self): + fn = os.path.join(TEST_DATA_DIR, "bom.py") + data = self.check_file_refactoring(fn) + self.assertTrue(data.startswith(codecs.BOM_UTF8)) + def test_crlf_newlines(self): old_sep = os.linesep os.linesep = "\r\n" From python-checkins at python.org Fri Nov 13 23:57:33 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 22:57:33 -0000 Subject: [Python-checkins] r76251 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Fri Nov 13 23:57:33 2009 New Revision: 76251 Log: Blocked revisions 76243,76249 via svnmerge ........ r76243 | benjamin.peterson | 2009-11-13 16:17:17 -0600 (Fri, 13 Nov 2009) | 1 line never mind about eval mode in this case ........ r76249 | benjamin.peterson | 2009-11-13 16:56:00 -0600 (Fri, 13 Nov 2009) | 1 line revert r76243; I was right, actually :) ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Nov 13 23:58:37 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 22:58:37 -0000 Subject: [Python-checkins] r76252 - sandbox/trunk/2to3/lib2to3/tests/test_parser.py Message-ID: Author: benjamin.peterson Date: Fri Nov 13 23:58:36 2009 New Revision: 76252 Log: remove pdb turd Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py Modified: sandbox/trunk/2to3/lib2to3/tests/test_parser.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_parser.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_parser.py Fri Nov 13 23:58:36 2009 @@ -161,7 +161,6 @@ tree = driver.parse_string(source) new = unicode(tree) if diff(filepath, new, encoding): - import pdb; pdb.set_trace() self.fail("Idempotency failed: %s" % filepath) def test_extended_unpacking(self): From python-checkins at python.org Fri Nov 13 23:58:45 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 13 Nov 2009 22:58:45 -0000 Subject: [Python-checkins] r76253 - python/branches/py3k/Doc/whatsnew/3.2.rst Message-ID: Author: antoine.pitrou Date: Fri Nov 13 23:58:45 2009 New Revision: 76253 Log: Add a note about the RLock acceleration Modified: python/branches/py3k/Doc/whatsnew/3.2.rst Modified: python/branches/py3k/Doc/whatsnew/3.2.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.2.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.2.rst Fri Nov 13 23:58:45 2009 @@ -105,6 +105,12 @@ (Contributed by Antoine Pitrou) +* Recursive locks (created with the :func:`threading.RLock` API) now benefit + from a C implementation which makes them as fast as regular locks, and + between 10x and 15x faster than their previous pure Python implementation. + + (Contributed by Antoine Pitrou; :issue:`3001`.) + Optimizations ============= From python-checkins at python.org Sat Nov 14 00:11:55 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 23:11:55 -0000 Subject: [Python-checkins] r76255 - in python/trunk/Doc: Makefile make.bat Message-ID: Author: benjamin.peterson Date: Sat Nov 14 00:11:54 2009 New Revision: 76255 Log: use Sphinx 0.6.3 Modified: python/trunk/Doc/Makefile python/trunk/Doc/make.bat Modified: python/trunk/Doc/Makefile ============================================================================== --- python/trunk/Doc/Makefile (original) +++ python/trunk/Doc/Makefile Sat Nov 14 00:11:54 2009 @@ -32,7 +32,7 @@ checkout: @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ - svn checkout $(SVNROOT)/external/Sphinx-0.6.2/sphinx tools/sphinx; \ + svn checkout $(SVNROOT)/external/Sphinx-0.6.3/sphinx tools/sphinx; \ fi @if [ ! -d tools/docutils ]; then \ echo "Checking out Docutils..."; \ Modified: python/trunk/Doc/make.bat ============================================================================== --- python/trunk/Doc/make.bat (original) +++ python/trunk/Doc/make.bat Sat Nov 14 00:11:54 2009 @@ -34,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/external/Sphinx-0.6.2/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.3/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From python-checkins at python.org Sat Nov 14 00:14:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 23:14:25 -0000 Subject: [Python-checkins] r76256 - in python/branches/py3k: Doc/Makefile Doc/make.bat Message-ID: Author: benjamin.peterson Date: Sat Nov 14 00:14:24 2009 New Revision: 76256 Log: Merged revisions 76255 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76255 | benjamin.peterson | 2009-11-13 17:11:54 -0600 (Fri, 13 Nov 2009) | 1 line use Sphinx 0.6.3 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/Makefile python/branches/py3k/Doc/make.bat Modified: python/branches/py3k/Doc/Makefile ============================================================================== --- python/branches/py3k/Doc/Makefile (original) +++ python/branches/py3k/Doc/Makefile Sat Nov 14 00:14:24 2009 @@ -32,7 +32,7 @@ checkout: @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ - svn checkout $(SVNROOT)/external/Sphinx-0.6.2/sphinx tools/sphinx; \ + svn checkout $(SVNROOT)/external/Sphinx-0.6.3/sphinx tools/sphinx; \ fi @if [ ! -d tools/docutils ]; then \ echo "Checking out Docutils..."; \ Modified: python/branches/py3k/Doc/make.bat ============================================================================== --- python/branches/py3k/Doc/make.bat (original) +++ python/branches/py3k/Doc/make.bat Sat Nov 14 00:14:24 2009 @@ -34,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/external/Sphinx-0.6.2/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.3/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From python-checkins at python.org Sat Nov 14 00:14:55 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 23:14:55 -0000 Subject: [Python-checkins] r76257 - in python/branches/release26-maint: Doc/Makefile Doc/make.bat Message-ID: Author: benjamin.peterson Date: Sat Nov 14 00:14:55 2009 New Revision: 76257 Log: Merged revisions 76255 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76255 | benjamin.peterson | 2009-11-13 17:11:54 -0600 (Fri, 13 Nov 2009) | 1 line use Sphinx 0.6.3 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/Makefile python/branches/release26-maint/Doc/make.bat Modified: python/branches/release26-maint/Doc/Makefile ============================================================================== --- python/branches/release26-maint/Doc/Makefile (original) +++ python/branches/release26-maint/Doc/Makefile Sat Nov 14 00:14:55 2009 @@ -32,7 +32,7 @@ checkout: @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ - svn checkout $(SVNROOT)/external/Sphinx-0.6.2/sphinx tools/sphinx; \ + svn checkout $(SVNROOT)/external/Sphinx-0.6.3/sphinx tools/sphinx; \ fi @if [ ! -d tools/docutils ]; then \ echo "Checking out Docutils..."; \ Modified: python/branches/release26-maint/Doc/make.bat ============================================================================== --- python/branches/release26-maint/Doc/make.bat (original) +++ python/branches/release26-maint/Doc/make.bat Sat Nov 14 00:14:55 2009 @@ -34,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/external/Sphinx-0.6.2/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.3/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From python-checkins at python.org Sat Nov 14 00:15:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 13 Nov 2009 23:15:59 -0000 Subject: [Python-checkins] r76258 - in python/branches/release31-maint: Doc/Makefile Doc/make.bat Message-ID: Author: benjamin.peterson Date: Sat Nov 14 00:15:59 2009 New Revision: 76258 Log: Merged revisions 76256 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76256 | benjamin.peterson | 2009-11-13 17:14:24 -0600 (Fri, 13 Nov 2009) | 9 lines Merged revisions 76255 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76255 | benjamin.peterson | 2009-11-13 17:11:54 -0600 (Fri, 13 Nov 2009) | 1 line use Sphinx 0.6.3 ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/Makefile python/branches/release31-maint/Doc/make.bat Modified: python/branches/release31-maint/Doc/Makefile ============================================================================== --- python/branches/release31-maint/Doc/Makefile (original) +++ python/branches/release31-maint/Doc/Makefile Sat Nov 14 00:15:59 2009 @@ -32,7 +32,7 @@ checkout: @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ - svn checkout $(SVNROOT)/external/Sphinx-0.6.2/sphinx tools/sphinx; \ + svn checkout $(SVNROOT)/external/Sphinx-0.6.3/sphinx tools/sphinx; \ fi @if [ ! -d tools/docutils ]; then \ echo "Checking out Docutils..."; \ Modified: python/branches/release31-maint/Doc/make.bat ============================================================================== --- python/branches/release31-maint/Doc/make.bat (original) +++ python/branches/release31-maint/Doc/make.bat Sat Nov 14 00:15:59 2009 @@ -34,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/external/Sphinx-0.6.2/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.3/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From g.brandl at gmx.net Sat Nov 14 12:49:21 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Sat, 14 Nov 2009 12:49:21 +0100 Subject: [Python-checkins] r76230 - in python/trunk: Doc/library/functions.rst Lib/test/test_codeop.py Lib/test/test_compile.py Lib/test/test_parser.py Misc/NEWS Parser/parsetok.c Parser/tokenizer.c Parser/tokenizer.h In-Reply-To: <1afaf6160911131454v21f6de59mcda62f778e3a676c@mail.gmail.com> References: <678.629466756497$1258069606@news.gmane.org> <4AFDDC9D.1080605@gmail.com> <1afaf6160911131454v21f6de59mcda62f778e3a676c@mail.gmail.com> Message-ID: Benjamin Peterson schrieb: > 2009/11/13 Nick Coghlan : >> You can do that with line continuations and bracket matching. >> >>>>>code = compile("sys.stdout.write(str(\n1\n+\n1)+'\\n')\n", >> "", "eval") >>>>> import sys >>>>> exec code >> 2 > > Thank you! I knew there was some reason, but I couldn't remember it. :) OK, but it shouldn't be called "statements" then. I'll change it to "multi-line code". Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out. From python-checkins at python.org Sat Nov 14 12:50:52 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 14 Nov 2009 11:50:52 -0000 Subject: [Python-checkins] r76259 - python/trunk/Doc/library/functions.rst Message-ID: Author: georg.brandl Date: Sat Nov 14 12:50:51 2009 New Revision: 76259 Log: Fix terminology. Modified: python/trunk/Doc/library/functions.rst Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Sat Nov 14 12:50:51 2009 @@ -173,7 +173,7 @@ .. note:: - When compiling a string with multi-line statements in ``'single'`` or + When compiling a string with multi-line code in ``'single'`` or ``'eval'`` mode, input must be terminated by at least one newline character. This is to facilitate detection of incomplete and complete statements in the :mod:`code` module. From python-checkins at python.org Sat Nov 14 16:18:22 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 15:18:22 -0000 Subject: [Python-checkins] r76260 - in python/trunk: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sat Nov 14 16:18:22 2009 New Revision: 76260 Log: Issue #7312 (new feature): Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. Patch by Antoine Pitrou. Modified: python/trunk/Lib/test/regrtest.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Sat Nov 14 16:18:22 2009 @@ -43,6 +43,7 @@ -N/--nocoverdir -- Put coverage files alongside modules -t/--threshold THRESHOLD -- call gc.set_threshold(THRESHOLD) +-F/--forever -- run the selected tests in a loop, until an error happens If non-option arguments are present, they are names for tests to run, unless -x is given, in which case they are names for tests not to run. @@ -150,6 +151,7 @@ import cStringIO import getopt +import itertools import json import os import random @@ -219,7 +221,7 @@ exclude=False, single=False, randomize=False, fromfile=None, findleaks=False, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, - random_seed=None, use_mp=None, verbose3=False): + random_seed=None, use_mp=None, verbose3=False, forever=False): """Execute a test suite. This also parses command-line options and modifies its behavior @@ -244,12 +246,12 @@ test_support.record_original_stdout(sys.stdout) try: - opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:wWM:j:', + opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:FwWM:j:', ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', 'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=', - 'multiprocess=', 'slaveargs=']) + 'multiprocess=', 'slaveargs=', 'forever']) except getopt.error, msg: usage(2, msg) @@ -329,6 +331,8 @@ use_resources.remove(r) elif r not in use_resources: use_resources.append(r) + elif o in ('-F', '--forever'): + forever = True elif o in ('-j', '--multiprocess'): use_mp = int(a) elif o == '--slaveargs': @@ -371,8 +375,8 @@ filename = os.path.join(gettempdir(), 'pynexttest') try: fp = open(filename, 'r') - next = fp.read().strip() - tests = [next] + next_test = fp.read().strip() + tests = [next_test] fp.close() except IOError: pass @@ -411,6 +415,7 @@ import trace tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], trace=False, count=True) + test_times = [] test_support.use_resources = use_resources save_modules = sys.modules.keys() @@ -431,6 +436,17 @@ skipped.append(test) resource_denieds.append(test) + if forever: + def test_forever(tests=list(tests)): + while True: + for test in tests: + yield test + if bad: + return + tests = test_forever() + else: + tests = iter(tests) + if use_mp: from threading import Thread from Queue import Queue, Empty @@ -439,19 +455,21 @@ debug_output_pat = re.compile(r"\[\d+ refs\]$") pending = deque() output = Queue() - for test in tests: - args_tuple = ( - (test, verbose, quiet, testdir), - dict(huntrleaks=huntrleaks, use_resources=use_resources) - ) - pending.append((test, args_tuple)) + def tests_and_args(): + for test in tests: + args_tuple = ( + (test, verbose, quiet, testdir), + dict(huntrleaks=huntrleaks, use_resources=use_resources) + ) + yield (test, args_tuple) + pending = tests_and_args() def work(): # A worker thread. try: while True: try: - test, args_tuple = pending.popleft() - except IndexError: + test, args_tuple = next(pending) + except StopIteration: output.put((None, None, None, None)) return # -E is needed by some tests, e.g. test_import @@ -464,6 +482,9 @@ # comes from the shutdown of the interpreter in the subcommand. stderr = debug_output_pat.sub("", stderr) stdout, _, result = stdout.strip().rpartition("\n") + if not result: + output.put((None, None, None, None)) + return result = json.loads(result) if not quiet: stdout = test+'\n'+stdout @@ -475,20 +496,22 @@ for worker in workers: worker.start() finished = 0 - while finished < use_mp: - test, stdout, stderr, result = output.get() - if test is None: - finished += 1 - continue - if stdout: - print stdout - if stderr: - print >>sys.stderr, stderr - if result[0] == INTERRUPTED: - assert result[1] == 'KeyboardInterrupt' - pending.clear() - raise KeyboardInterrupt # What else? - accumulate_result(test, result) + try: + while finished < use_mp: + test, stdout, stderr, result = output.get() + if test is None: + finished += 1 + continue + if stdout: + print stdout + if stderr: + print >>sys.stderr, stderr + if result[0] == INTERRUPTED: + assert result[1] == 'KeyboardInterrupt' + raise KeyboardInterrupt # What else? + accumulate_result(test, result) + except KeyboardInterrupt: + pending.close() for worker in workers: worker.join() else: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Nov 14 16:18:22 2009 @@ -1567,6 +1567,9 @@ Tests ----- +- Issue #7312: Add a -F flag to run the selected tests in a loop until + a test fails. Can be combined with -j. + - Issue #7295: Do not use a hardcoded file name in test_tarfile. - Issue #7270: Add some dedicated unit tests for multi-thread synchronization From python-checkins at python.org Sat Nov 14 17:13:02 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 16:13:02 -0000 Subject: [Python-checkins] r76261 - in python/branches/py3k: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sat Nov 14 17:13:02 2009 New Revision: 76261 Log: Merged revisions 76260 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76260 | r.david.murray | 2009-11-14 10:18:22 -0500 (Sat, 14 Nov 2009) | 5 lines Issue #7312 (new feature): Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. Patch by Antoine Pitrou. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Sat Nov 14 17:13:02 2009 @@ -45,6 +45,7 @@ -t/--threshold THRESHOLD -- call gc.set_threshold(THRESHOLD) -n/--nowindows -- suppress error message boxes on Windows +-F/--forever -- run the selected tests in a loop, until an error happens If non-option arguments are present, they are names for tests to run, unless -x is given, in which case they are names for tests not to run. @@ -147,6 +148,7 @@ """ import getopt +import itertools import json import os import random @@ -217,7 +219,7 @@ exclude=False, single=False, randomize=False, fromfile=None, findleaks=False, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, - random_seed=None, use_mp=None, verbose3=False): + random_seed=None, use_mp=None, verbose3=False, forever=False): """Execute a test suite. This also parses command-line options and modifies its behavior @@ -243,12 +245,13 @@ support.record_original_stdout(sys.stdout) try: - opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:wWM:nj:', + opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:nj:', ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', - 'runleaks', 'huntrleaks=', 'memlimit=', 'debug', 'start=', - 'nowindows', 'randseed=', 'multiprocess=', 'slaveargs=']) + 'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=', + 'multiprocess=', 'slaveargs=', 'forever', 'debug', 'start=', + 'nowindows']) except getopt.error as msg: usage(msg) @@ -353,6 +356,8 @@ for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) + elif o in ('-F', '--forever'): + forever = True elif o in ('-j', '--multiprocess'): use_mp = int(a) elif o == '--slaveargs': @@ -396,8 +401,8 @@ filename = os.path.join(gettempdir(), 'pynexttest') try: fp = open(filename, 'r') - next = fp.read().strip() - tests = [next] + next_test = fp.read().strip() + tests = [next_test] fp.close() except IOError: pass @@ -443,6 +448,7 @@ tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix, tempfile.gettempdir()], trace=False, count=True) + test_times = [] support.verbose = verbose # Tell tests to be moderately quiet support.use_resources = use_resources @@ -464,6 +470,17 @@ skipped.append(test) resource_denieds.append(test) + if forever: + def test_forever(tests=list(tests)): + while True: + for test in tests: + yield test + if bad: + return + tests = test_forever() + else: + tests = iter(tests) + if use_mp: from threading import Thread from queue import Queue, Empty @@ -472,20 +489,22 @@ debug_output_pat = re.compile(r"\[\d+ refs\]$") pending = deque() output = Queue() - for test in tests: - args_tuple = ( - (test, verbose, quiet, testdir), - dict(huntrleaks=huntrleaks, use_resources=use_resources, - debug=debug) - ) - pending.append((test, args_tuple)) + def tests_and_args(): + for test in tests: + args_tuple = ( + (test, verbose, quiet, testdir), + dict(huntrleaks=huntrleaks, use_resources=use_resources, + debug=debug) + ) + yield (test, args_tuple) + pending = tests_and_args() def work(): # A worker thread. try: while True: try: - test, args_tuple = pending.popleft() - except IndexError: + test, args_tuple = next(pending) + except StopIteration: output.put((None, None, None, None)) return # -E is needed by some tests, e.g. test_import @@ -498,6 +517,9 @@ # comes from the shutdown of the interpreter in the subcommand. stderr = debug_output_pat.sub("", stderr) stdout, _, result = stdout.strip().rpartition("\n") + if not result: + output.put((None, None, None, None)) + return result = json.loads(result) if not quiet: stdout = test+'\n'+stdout @@ -509,20 +531,22 @@ for worker in workers: worker.start() finished = 0 - while finished < use_mp: - test, stdout, stderr, result = output.get() - if test is None: - finished += 1 - continue - if stdout: - print(stdout) - if stderr: - print(stderr, file=sys.stderr) - if result[0] == INTERRUPTED: - assert result[1] == 'KeyboardInterrupt' - pending.clear() - raise KeyboardInterrupt # What else? - accumulate_result(test, result) + try: + while finished < use_mp: + test, stdout, stderr, result = output.get() + if test is None: + finished += 1 + continue + if stdout: + print(stdout) + if stderr: + print(stderr, file=sys.stderr) + if result[0] == INTERRUPTED: + assert result[1] == 'KeyboardInterrupt' + raise KeyboardInterrupt # What else? + accumulate_result(test, result) + except KeyboardInterrupt: + pending.close() for worker in workers: worker.join() else: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Nov 14 17:13:02 2009 @@ -378,6 +378,9 @@ Tests ----- +- Issue #7312: Add a -F flag to run the selected tests in a loop until + a test fails. Can be combined with -j. + - Issue #6551: test_zipimport could import and then destroy some modules of the encodings package, which would make other tests fail further down the road because the internally cached encoders and decoders would point From python-checkins at python.org Sat Nov 14 17:21:12 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 16:21:12 -0000 Subject: [Python-checkins] r76262 - python/branches/release26-maint Message-ID: Author: r.david.murray Date: Sat Nov 14 17:21:12 2009 New Revision: 76262 Log: Blocked revisions 76260 via svnmerge ........ r76260 | r.david.murray | 2009-11-14 10:18:22 -0500 (Sat, 14 Nov 2009) | 5 lines Issue #7312 (new feature): Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. Patch by Antoine Pitrou. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Nov 14 17:22:13 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 16:22:13 -0000 Subject: [Python-checkins] r76263 - python/branches/release31-maint Message-ID: Author: r.david.murray Date: Sat Nov 14 17:22:13 2009 New Revision: 76263 Log: Blocked revisions 76261 via svnmerge ................ r76261 | r.david.murray | 2009-11-14 11:13:02 -0500 (Sat, 14 Nov 2009) | 11 lines Merged revisions 76260 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76260 | r.david.murray | 2009-11-14 10:18:22 -0500 (Sat, 14 Nov 2009) | 5 lines Issue #7312 (new feature): Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. Patch by Antoine Pitrou. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Nov 14 17:27:26 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2009 16:27:26 -0000 Subject: [Python-checkins] r76264 - python/branches/py3k/Lib/tokenize.py Message-ID: Author: benjamin.peterson Date: Sat Nov 14 17:27:26 2009 New Revision: 76264 Log: simply by using itertools.chain() Modified: python/branches/py3k/Lib/tokenize.py Modified: python/branches/py3k/Lib/tokenize.py ============================================================================== --- python/branches/py3k/Lib/tokenize.py (original) +++ python/branches/py3k/Lib/tokenize.py Sat Nov 14 17:27:26 2009 @@ -377,17 +377,12 @@ The first token sequence will always be an ENCODING token which tells you which encoding was used to decode the bytes stream. """ + # This import is here to avoid problems when the itertools module is not + # built yet and tokenize is imported. + from itertools import chain encoding, consumed = detect_encoding(readline) - def readline_generator(consumed): - for line in consumed: - yield line - while True: - try: - yield readline() - except StopIteration: - return - chained = readline_generator(consumed) - return _tokenize(chained.__next__, encoding) + rl_iter = iter(readline, "") + return _tokenize(chain(consumed, rl_iter).__next__, encoding) def _tokenize(readline, encoding): From python-checkins at python.org Sat Nov 14 18:43:16 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 17:43:16 -0000 Subject: [Python-checkins] r76265 - python/trunk/Lib/bsddb/test/test_replication.py Message-ID: Author: r.david.murray Date: Sat Nov 14 18:43:16 2009 New Revision: 76265 Log: Turn the bsddb replication startup timeout test into a warning, to improve buildbot stability. Modified: python/trunk/Lib/bsddb/test/test_replication.py Modified: python/trunk/Lib/bsddb/test/test_replication.py ============================================================================== --- python/trunk/Lib/bsddb/test/test_replication.py (original) +++ python/trunk/Lib/bsddb/test/test_replication.py Sat Nov 14 18:43:16 2009 @@ -130,8 +130,13 @@ print >> sys.stderr, \ "XXX - windows bsddb replication fails on windows and is skipped" print >> sys.stderr, "XXX - Please see issue #3892" - else: - self.assertTrue(time.time()timeout: + print >> sys.stderr, \ + "XXX - timeout before startup confirmed, see issue #3892." d = self.dbenvMaster.repmgr_site_list() self.assertEquals(len(d), 1) From python-checkins at python.org Sat Nov 14 19:09:17 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2009 18:09:17 -0000 Subject: [Python-checkins] r76266 - python/branches/py3k/Lib/tokenize.py Message-ID: Author: benjamin.peterson Date: Sat Nov 14 19:09:17 2009 New Revision: 76266 Log: use some more itertools magic to make '' be yielded after readline is done Modified: python/branches/py3k/Lib/tokenize.py Modified: python/branches/py3k/Lib/tokenize.py ============================================================================== --- python/branches/py3k/Lib/tokenize.py (original) +++ python/branches/py3k/Lib/tokenize.py Sat Nov 14 19:09:17 2009 @@ -379,10 +379,11 @@ """ # This import is here to avoid problems when the itertools module is not # built yet and tokenize is imported. - from itertools import chain + from itertools import chain, repeat encoding, consumed = detect_encoding(readline) - rl_iter = iter(readline, "") - return _tokenize(chain(consumed, rl_iter).__next__, encoding) + rl_gen = iter(readline, b"") + empty = repeat(b"") + return _tokenize(chain(consumed, rl_gen, empty).__next__, encoding) def _tokenize(readline, encoding): From python-checkins at python.org Sat Nov 14 19:20:57 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 18:20:57 -0000 Subject: [Python-checkins] r76267 - in python/branches/release26-maint: Lib/bsddb/test/test_replication.py Message-ID: Author: r.david.murray Date: Sat Nov 14 19:20:57 2009 New Revision: 76267 Log: Merged revisions 76265 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76265 | r.david.murray | 2009-11-14 12:43:16 -0500 (Sat, 14 Nov 2009) | 3 lines Turn the bsddb replication startup timeout test into a warning, to improve buildbot stability. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/bsddb/test/test_replication.py Modified: python/branches/release26-maint/Lib/bsddb/test/test_replication.py ============================================================================== --- python/branches/release26-maint/Lib/bsddb/test/test_replication.py (original) +++ python/branches/release26-maint/Lib/bsddb/test/test_replication.py Sat Nov 14 19:20:57 2009 @@ -130,8 +130,13 @@ print >> sys.stderr, \ "XXX - windows bsddb replication fails on windows and is skipped" print >> sys.stderr, "XXX - Please see issue #3892" - else: - self.assertTrue(time.time()timeout: + print >> sys.stderr, \ + "XXX - timeout before startup confirmed, see issue #3892." d = self.dbenvMaster.repmgr_site_list() self.assertEquals(len(d), 1) From python-checkins at python.org Sat Nov 14 19:26:33 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 18:26:33 -0000 Subject: [Python-checkins] r76268 - python/branches/py3k Message-ID: Author: r.david.murray Date: Sat Nov 14 19:26:33 2009 New Revision: 76268 Log: Blocked revisions 76214,76265 via svnmerge ........ r76214 | r.david.murray | 2009-11-11 13:07:27 -0500 (Wed, 11 Nov 2009) | 5 lines I got the relative magnitudes of the timeout increases reversed, so I'm bumping up the longer test to the 60 seconds I intended to make it. If this doesn't cure the intermittent buildbot timeouts, I'm going to turn that test into a warning rather than a failure. ........ r76265 | r.david.murray | 2009-11-14 12:43:16 -0500 (Sat, 14 Nov 2009) | 3 lines Turn the bsddb replication startup timeout test into a warning, to improve buildbot stability. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Nov 14 23:08:02 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 22:08:02 -0000 Subject: [Python-checkins] r76269 - in python/branches/release26-maint: Doc/faq/programming.rst Message-ID: Author: r.david.murray Date: Sat Nov 14 23:08:02 2009 New Revision: 76269 Log: Merged revisions 76190 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76190 | r.david.murray | 2009-11-10 13:58:02 -0500 (Tue, 10 Nov 2009) | 3 lines Update the FAQ entry that explains that assignments in the local scope shadow variables in the outer scope (issue 7290). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/faq/programming.rst Modified: python/branches/release26-maint/Doc/faq/programming.rst ============================================================================== --- python/branches/release26-maint/Doc/faq/programming.rst (original) +++ python/branches/release26-maint/Doc/faq/programming.rst Sat Nov 14 23:08:02 2009 @@ -277,39 +277,77 @@ Core Language ============= -How do you set a global variable in a function? ------------------------------------------------ - -Did you do something like this? :: - - x = 1 # make a global - - def f(): - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 - -Any variable assigned in a function is local to that function. unless it is -specifically declared global. Since a value is bound to ``x`` as the last -statement of the function body, the compiler assumes that ``x`` is -local. Consequently the ``print x`` attempts to print an uninitialized local -variable and will trigger a ``NameError``. - -The solution is to insert an explicit global declaration at the start of the -function:: - - def f(): - global x - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 +Why am I getting an UnboundLocalError when the variable has a value? +-------------------------------------------------------------------- -In this case, all references to ``x`` are interpreted as references to the ``x`` -from the module namespace. +It can be a surprise to get the UnboundLocalError in previously working +code when it is modified by adding an assignment statement somewhere in +the body of a function. + +This code: + + >>> x = 10 + >>> def bar(): + ... print x + >>> bar() + 10 + +works, but this code: + + >>> x = 10 + >>> def foo(): + ... print x + ... x += 1 + +results in an UnboundLocalError: + + >>> foo() + Traceback (most recent call last): + ... + UnboundLocalError: local variable 'x' referenced before assignment + +This is because when you make an assignment to a variable in a scope, that +variable becomes local to that scope and shadows any similarly named variable +in the outer scope. Since the last statement in foo assigns a new value to +``x``, the compiler recognizes it as a local variable. Consequently when the +earlier ``print x`` attempts to print the uninitialized local variable and +an error results. + +In the example above you can access the outer scope variable by declaring it +global: + + >>> x = 10 + >>> def foobar(): + ... global x + ... print x + ... x += 1 + >>> foobar() + 10 + +This explicit declaration is required in order to remind you that (unlike the +superficially analogous situation with class and instance variables) you are +actually modifying the value of the variable in the outer scope: + + >>> print x + 11 + +In Python3, you can do a similar thing in a nested scope using the +:keyword:`nonlocal` keyword: + +.. doctest:: + :options: +SKIP + + >>> def foo(): + ... x = 10 + ... def bar(): + ... nonlocal x + ... print x + ... x += 1 + ... bar() + ... print x + >>> foo() + 10 + 11 What are the rules for local and global variables in Python? From python-checkins at python.org Sat Nov 14 23:21:32 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 22:21:32 -0000 Subject: [Python-checkins] r76270 - in python/branches/py3k: Doc/faq/programming.rst Message-ID: Author: r.david.murray Date: Sat Nov 14 23:21:32 2009 New Revision: 76270 Log: Merged revisions 76190 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76190 | r.david.murray | 2009-11-10 13:58:02 -0500 (Tue, 10 Nov 2009) | 3 lines Update the FAQ entry that explains that assignments in the local scope shadow variables in the outer scope (issue 7290). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/faq/programming.rst Modified: python/branches/py3k/Doc/faq/programming.rst ============================================================================== --- python/branches/py3k/Doc/faq/programming.rst (original) +++ python/branches/py3k/Doc/faq/programming.rst Sat Nov 14 23:21:32 2009 @@ -277,39 +277,74 @@ Core Language ============= -How do you set a global variable in a function? ------------------------------------------------ - -Did you do something like this? :: - - x = 1 # make a global - - def f(): - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 - -Any variable assigned in a function is local to that function. unless it is -specifically declared global. Since a value is bound to ``x`` as the last -statement of the function body, the compiler assumes that ``x`` is -local. Consequently the ``print x`` attempts to print an uninitialized local -variable and will trigger a ``NameError``. - -The solution is to insert an explicit global declaration at the start of the -function:: - - def f(): - global x - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 +Why am I getting an UnboundLocalError when the variable has a value? +-------------------------------------------------------------------- -In this case, all references to ``x`` are interpreted as references to the ``x`` -from the module namespace. +It can be a surprise to get the UnboundLocalError in previously working +code when it is modified by adding an assignment statement somewhere in +the body of a function. + +This code: + + >>> x = 10 + >>> def bar(): + ... print(x) + >>> bar() + 10 + +works, but this code: + + >>> x = 10 + >>> def foo(): + ... print(x) + ... x += 1 + +results in an UnboundLocalError: + + >>> foo() + Traceback (most recent call last): + ... + UnboundLocalError: local variable 'x' referenced before assignment + +This is because when you make an assignment to a variable in a scope, that +variable becomes local to that scope and shadows any similarly named variable +in the outer scope. Since the last statement in foo assigns a new value to +``x``, the compiler recognizes it as a local variable. Consequently when the +earlier ``print x`` attempts to print the uninitialized local variable and +an error results. + +In the example above you can access the outer scope variable by declaring it +global: + + >>> x = 10 + >>> def foobar(): + ... global x + ... print(x) + ... x += 1 + >>> foobar() + 10 + +This explicit declaration is required in order to remind you that (unlike the +superficially analogous situation with class and instance variables) you are +actually modifying the value of the variable in the outer scope: + + >>> print(x) + 11 + +You can do a similar thing in a nested scope using the :keyword:`nonlocal` +keyword: + + >>> def foo(): + ... x = 10 + ... def bar(): + ... nonlocal x + ... print(x) + ... x += 1 + ... bar() + ... print(x) + >>> foo() + 10 + 11 What are the rules for local and global variables in Python? From python-checkins at python.org Sat Nov 14 23:24:15 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 22:24:15 -0000 Subject: [Python-checkins] r76271 - in python/branches/release31-maint: Doc/faq/programming.rst Message-ID: Author: r.david.murray Date: Sat Nov 14 23:24:15 2009 New Revision: 76271 Log: Merged revisions 76270 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76270 | r.david.murray | 2009-11-14 17:21:32 -0500 (Sat, 14 Nov 2009) | 10 lines Merged revisions 76190 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76190 | r.david.murray | 2009-11-10 13:58:02 -0500 (Tue, 10 Nov 2009) | 3 lines Update the FAQ entry that explains that assignments in the local scope shadow variables in the outer scope (issue 7290). ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/faq/programming.rst Modified: python/branches/release31-maint/Doc/faq/programming.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/programming.rst (original) +++ python/branches/release31-maint/Doc/faq/programming.rst Sat Nov 14 23:24:15 2009 @@ -277,39 +277,74 @@ Core Language ============= -How do you set a global variable in a function? ------------------------------------------------ - -Did you do something like this? :: - - x = 1 # make a global - - def f(): - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 - -Any variable assigned in a function is local to that function. unless it is -specifically declared global. Since a value is bound to ``x`` as the last -statement of the function body, the compiler assumes that ``x`` is -local. Consequently the ``print x`` attempts to print an uninitialized local -variable and will trigger a ``NameError``. - -The solution is to insert an explicit global declaration at the start of the -function:: - - def f(): - global x - print x # try to print the global - ... - for j in range(100): - if q > 3: - x = 4 +Why am I getting an UnboundLocalError when the variable has a value? +-------------------------------------------------------------------- -In this case, all references to ``x`` are interpreted as references to the ``x`` -from the module namespace. +It can be a surprise to get the UnboundLocalError in previously working +code when it is modified by adding an assignment statement somewhere in +the body of a function. + +This code: + + >>> x = 10 + >>> def bar(): + ... print(x) + >>> bar() + 10 + +works, but this code: + + >>> x = 10 + >>> def foo(): + ... print(x) + ... x += 1 + +results in an UnboundLocalError: + + >>> foo() + Traceback (most recent call last): + ... + UnboundLocalError: local variable 'x' referenced before assignment + +This is because when you make an assignment to a variable in a scope, that +variable becomes local to that scope and shadows any similarly named variable +in the outer scope. Since the last statement in foo assigns a new value to +``x``, the compiler recognizes it as a local variable. Consequently when the +earlier ``print x`` attempts to print the uninitialized local variable and +an error results. + +In the example above you can access the outer scope variable by declaring it +global: + + >>> x = 10 + >>> def foobar(): + ... global x + ... print(x) + ... x += 1 + >>> foobar() + 10 + +This explicit declaration is required in order to remind you that (unlike the +superficially analogous situation with class and instance variables) you are +actually modifying the value of the variable in the outer scope: + + >>> print(x) + 11 + +You can do a similar thing in a nested scope using the :keyword:`nonlocal` +keyword: + + >>> def foo(): + ... x = 10 + ... def bar(): + ... nonlocal x + ... print(x) + ... x += 1 + ... bar() + ... print(x) + >>> foo() + 10 + 11 What are the rules for local and global variables in Python? From python-checkins at python.org Sat Nov 14 23:27:23 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 22:27:23 -0000 Subject: [Python-checkins] r76272 - python/branches/py3k/Doc/faq/programming.rst Message-ID: Author: r.david.murray Date: Sat Nov 14 23:27:22 2009 New Revision: 76272 Log: Fix print function conversion missed in merge of faq/programming update. Modified: python/branches/py3k/Doc/faq/programming.rst Modified: python/branches/py3k/Doc/faq/programming.rst ============================================================================== --- python/branches/py3k/Doc/faq/programming.rst (original) +++ python/branches/py3k/Doc/faq/programming.rst Sat Nov 14 23:27:22 2009 @@ -310,7 +310,7 @@ variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to ``x``, the compiler recognizes it as a local variable. Consequently when the -earlier ``print x`` attempts to print the uninitialized local variable and +earlier ``print(x)`` attempts to print the uninitialized local variable and an error results. In the example above you can access the outer scope variable by declaring it From python-checkins at python.org Sat Nov 14 23:28:36 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 14 Nov 2009 22:28:36 -0000 Subject: [Python-checkins] r76273 - in python/branches/release31-maint: Doc/faq/programming.rst Message-ID: Author: r.david.murray Date: Sat Nov 14 23:28:36 2009 New Revision: 76273 Log: Merged revisions 76272 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76272 | r.david.murray | 2009-11-14 17:27:22 -0500 (Sat, 14 Nov 2009) | 2 lines Fix print function conversion missed in merge of faq/programming update. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/faq/programming.rst Modified: python/branches/release31-maint/Doc/faq/programming.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/programming.rst (original) +++ python/branches/release31-maint/Doc/faq/programming.rst Sat Nov 14 23:28:36 2009 @@ -310,7 +310,7 @@ variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to ``x``, the compiler recognizes it as a local variable. Consequently when the -earlier ``print x`` attempts to print the uninitialized local variable and +earlier ``print(x)`` attempts to print the uninitialized local variable and an error results. In the example above you can access the outer scope variable by declaring it From solipsis at pitrou.net Sun Nov 15 00:46:35 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 15 Nov 2009 00:46:35 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76266): sum=12 Message-ID: <20091114234635.9B54B17715@ns6635.ovh.net> py3k results for svn r76266 (hg cset 7e327b154877) -------------------------------------------------- test_urllib leaked [8, 2, 2] references, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogYboLvH', '-x', 'test_httpservers'] From python-checkins at python.org Sun Nov 15 00:55:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 14 Nov 2009 23:55:18 -0000 Subject: [Python-checkins] r76274 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Sun Nov 15 00:55:17 2009 New Revision: 76274 Log: added the environment markers Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Sun Nov 15 00:55:17 2009 @@ -444,11 +444,69 @@ XXX command-line interface needs work, obviously +Environment markers +=================== + +An **environment marker** is a marker that can be added at the end of a +field after a semi-colon (';'), to add a condition about the execution +environment. + +Here are some example of fields using such markers:: + + Requires-Dist: pywin32, bar > 1.0; sys.platform == 'win32' + Obsoletes-Dist: pywin31; sys.platform == 'win32' + Requires-Dist: foo; os.machine == 'i386' + Requires-Dist: bar; python_version == '2.4' or python_version == '2.5' + Requires-External: libxslt; 'linux' in sys.platform + +These markers are using a micro-language that can be interpreted using a +function ``interpret_marker`` provided in the ``distutils.util`` module +in the stdlib:: + + >>> from distutils.util import + >>> interpret_marker("sys.platform == 'win32'") + True + +Depending if the execution environment meets the requirements, the function +will return True or False. + +The micro-language behind this is the simplest possible: it compares only +strings, with the ``==`` and ``in`` operators (and their opposites), and +with the ability to combine expressions. It makes it also easy to understand +to non-pythoneers. + +The pseudo-grammar is :: + + EXPR [in|==|!=|not in]?EXPR [or|and] ... + +where ``EXPR`` belongs to any of those: + +- python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1]) +- os.name = os.name +- sys.platform = sys.platform +- platform.version = platform.version() +- platform.machine = platform.machine() +- a free string, like ``2.4``, or ``win32`` + +Notice that ``in`` is restricted to strings, meaning that it is not possible +to use other sequences like tuples or lists on the right side. + +The fields that benefit from this marker are: + +- Requires-Python +- Requires-External +- Requires-Dist +- Provides-Dist +- Obsoletes-Dist +- Classifier + Summary of Differences From PEP 314 =================================== * Metadata-Version is now 1.2. +* Added the environment markers. + * Added fields: - Maintainer @@ -494,6 +552,9 @@ Fred Drake, Anthony Baxter and Matthias Klose have all contributed to the ideas presented in this PEP. +Tres Seaver, Jim Fulton, Marc-Andr? Lemburg, Tarek Ziad? and other people at +the Distutils-SIG have contributed to the new updated version. + .. Local Variables: From python-checkins at python.org Sun Nov 15 00:56:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 14 Nov 2009 23:56:18 -0000 Subject: [Python-checkins] r76275 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Sun Nov 15 00:56:18 2009 New Revision: 76275 Log: fixed the example Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Sun Nov 15 00:56:18 2009 @@ -403,8 +403,8 @@ Examples:: - Requires: C - Requires: libpng (>=1.5) + Requires-External: C + Requires-External: libpng (>=1.5) Copyright From python-checkins at python.org Sun Nov 15 01:04:32 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 15 Nov 2009 00:04:32 -0000 Subject: [Python-checkins] r76276 - in python/trunk: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Nov 15 01:04:32 2009 New Revision: 76276 Log: Issue 7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. Modified: python/trunk/Lib/test/regrtest.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Sun Nov 15 01:04:32 2009 @@ -344,6 +344,10 @@ print # Force a newline (just in case) print json.dumps(result) sys.exit(0) + else: + print >>sys.stderr, ("No handler for option {}. Please " + "report this as a bug at http://bugs.python.org.").format(o) + sys.exit(1) if single and fromfile: usage(2, "-s and -f don't go together!") if use_mp and trace: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 15 01:04:32 2009 @@ -1567,6 +1567,9 @@ Tests ----- +- Issue #7324: add a sanity check to regrtest argument parsing to + catch the case of an option with no handler. + - Issue #7312: Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. From python-checkins at python.org Sun Nov 15 01:07:01 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 15 Nov 2009 00:07:01 -0000 Subject: [Python-checkins] r76277 - python/trunk/Lib/test/regrtest.py Message-ID: Author: r.david.murray Date: Sun Nov 15 01:07:00 2009 New Revision: 76277 Log: Remove 'g' from regrtest getopt argument string, since there's no handler for it. Modified: python/trunk/Lib/test/regrtest.py Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Sun Nov 15 01:07:00 2009 @@ -246,7 +246,7 @@ test_support.record_original_stdout(sys.stdout) try: - opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:FwWM:j:', + opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:', ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', From python-checkins at python.org Sun Nov 15 01:17:18 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 15 Nov 2009 00:17:18 -0000 Subject: [Python-checkins] r76278 - in python/branches/release26-maint: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Nov 15 01:17:17 2009 New Revision: 76278 Log: Merged revisions 76276-76277 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76276 | r.david.murray | 2009-11-14 19:04:32 -0500 (Sat, 14 Nov 2009) | 3 lines Issue 7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. ........ r76277 | r.david.murray | 2009-11-14 19:07:00 -0500 (Sat, 14 Nov 2009) | 3 lines Remove 'g' from regrtest getopt argument string, since there's no handler for it. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/regrtest.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/test/regrtest.py ============================================================================== --- python/branches/release26-maint/Lib/test/regrtest.py (original) +++ python/branches/release26-maint/Lib/test/regrtest.py Sun Nov 15 01:17:17 2009 @@ -205,7 +205,7 @@ test_support.record_original_stdout(sys.stdout) try: - opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:wM:', + opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:wM:', ['help', 'verbose', 'quiet', 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', 'use=', 'threshold=', 'trace', @@ -285,6 +285,10 @@ use_resources.remove(r) elif r not in use_resources: use_resources.append(r) + else: + print >>sys.stderr, ("No handler for option {0}. Please " + "report this as a bug at http://bugs.python.org.").format(o) + sys.exit(1) if single and fromfile: usage(2, "-s and -f don't go together!") Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Nov 15 01:17:17 2009 @@ -82,6 +82,9 @@ Tests ----- +- Issue #7324: add a sanity check to regrtest argument parsing to + catch the case of an option with no handler. + - Issue #7295: Do not use a hardcoded file name in test_tarfile. - Issue #7270: Add some dedicated unit tests for multi-thread synchronization From python-checkins at python.org Sun Nov 15 01:23:21 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 15 Nov 2009 00:23:21 -0000 Subject: [Python-checkins] r76279 - in python/branches/py3k: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Nov 15 01:23:21 2009 New Revision: 76279 Log: Merged revisions 76276 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76276 | r.david.murray | 2009-11-14 19:04:32 -0500 (Sat, 14 Nov 2009) | 3 lines Issue 7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Sun Nov 15 01:23:21 2009 @@ -370,6 +370,10 @@ print() # Force a newline (just in case) print(json.dumps(result)) sys.exit(0) + else: + print(("No handler for option {}. Please report this as a bug " + "at http://bugs.python.org.").format(o), file=sys.stderr) + sys.exit(1) if single and fromfile: usage("-s and -f don't go together!") if use_mp and trace: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 15 01:23:21 2009 @@ -378,6 +378,9 @@ Tests ----- +- Issue #7324: add a sanity check to regrtest argument parsing to + catch the case of an option with no handler. + - Issue #7312: Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. From python-checkins at python.org Sun Nov 15 01:25:11 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 15 Nov 2009 00:25:11 -0000 Subject: [Python-checkins] r76280 - python/branches/py3k Message-ID: Author: r.david.murray Date: Sun Nov 15 01:25:11 2009 New Revision: 76280 Log: Blocked revisions 76277 via svnmerge ........ r76277 | r.david.murray | 2009-11-14 19:07:00 -0500 (Sat, 14 Nov 2009) | 3 lines Remove 'g' from regrtest getopt argument string, since there's no handler for it. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Nov 15 01:35:38 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 15 Nov 2009 00:35:38 -0000 Subject: [Python-checkins] r76281 - in python/branches/release31-maint: Lib/test/regrtest.py Misc/NEWS Message-ID: Author: r.david.murray Date: Sun Nov 15 01:35:37 2009 New Revision: 76281 Log: Merged revisions 76279 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76279 | r.david.murray | 2009-11-14 19:23:21 -0500 (Sat, 14 Nov 2009) | 10 lines Merged revisions 76276 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76276 | r.david.murray | 2009-11-14 19:04:32 -0500 (Sat, 14 Nov 2009) | 3 lines Issue 7324: add a sanity check to regrtest argument parsing to catch the case of an option with no handler. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/regrtest.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/test/regrtest.py ============================================================================== --- python/branches/release31-maint/Lib/test/regrtest.py (original) +++ python/branches/release31-maint/Lib/test/regrtest.py Sun Nov 15 01:35:37 2009 @@ -330,6 +330,10 @@ for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) + else: + print(("No handler for option {}. Please report this as a bug " + "at http://bugs.python.org.").format(o), file=sys.stderr) + sys.exit(1) if generate and verbose: usage("-g and -v don't go together!") if single and fromfile: Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Nov 15 01:35:37 2009 @@ -149,6 +149,9 @@ Tests ----- +- Issue #7324: add a sanity check to regrtest argument parsing to + catch the case of an option with no handler. + - Issue #6551: test_zipimport could import and then destroy some modules of the encodings package, which would make other tests fail further down the road because the internally cached encoders and decoders would point From ncoghlan at gmail.com Sun Nov 15 04:06:48 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sun, 15 Nov 2009 13:06:48 +1000 Subject: [Python-checkins] Using itertools in modules that are part of the build chain (Re: r76264 - python/branches/py3k/Lib/tokenize.py) In-Reply-To: <4afeda77.0702d00a.4fa1.488cSMTPIN_ADDED@mx.google.com> References: <4afeda77.0702d00a.4fa1.488cSMTPIN_ADDED@mx.google.com> Message-ID: <4AFF7048.7070701@gmail.com> benjamin.peterson wrote: > Modified: python/branches/py3k/Lib/tokenize.py > ============================================================================== > --- python/branches/py3k/Lib/tokenize.py (original) > +++ python/branches/py3k/Lib/tokenize.py Sat Nov 14 17:27:26 2009 > @@ -377,17 +377,12 @@ > The first token sequence will always be an ENCODING token > which tells you which encoding was used to decode the bytes stream. > """ > + # This import is here to avoid problems when the itertools module is not > + # built yet and tokenize is imported. > + from itertools import chain This is probably a bad idea - calling tokenize.tokenize() from a thread started as a side effect of importing a module will now deadlock on the import lock if the module import waits for that thread to finish. We tell people not to do that (starting and then waiting on threads as part of module import) for exactly this reason, but it is also the reason we avoid embedding import statements inside functions in the standard library (not to mention encouraging third party developers to also avoid embedding import statements inside functions). This does constrain where we can use itertools - if we want carte blanche to use it anywhere in the standard library, even those parts that are imported as part of the build chain, we'll need to bite the bullet and make it a builtin module rather than a separately built extension module. Cheers, Nick. P.S. The problem is easy to demonstrate on the current Py3k branch: 1. Put this in a module file in your py3k directory (e.g. "deadlock.py"): ----------- import threading import tokenize f = open(__file__, 'rU') def _deadlocks(): tokenize.tokenize(f.readline) t = threading.Thread(target=_deadlocks) t.start() t.join() ----------- 2. Then run: ./python -c "import deadlock" It will, as advertised, deadlock and you'll need to use Ctrl-Brk or kill -9 to get rid of it. (Note that preventing this kind of thing is one of the major reasons why direct execution and even the -m switch *don't* hang onto the import lock while running the __main__ module) -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From benjamin at python.org Sun Nov 15 05:01:07 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sat, 14 Nov 2009 22:01:07 -0600 Subject: [Python-checkins] Using itertools in modules that are part of the build chain (Re: r76264 - python/branches/py3k/Lib/tokenize.py) In-Reply-To: <4AFF7048.7070701@gmail.com> References: <4afeda77.0702d00a.4fa1.488cSMTPIN_ADDED@mx.google.com> <4AFF7048.7070701@gmail.com> Message-ID: <1afaf6160911142001m39d0f0ceyd3646e922d3bf703@mail.gmail.com> 2009/11/14 Nick Coghlan : > This does constrain where we can use itertools - if we want carte > blanche to use it anywhere in the standard library, even those parts > that are imported as part of the build chain, we'll need to bite the > bullet and make it a builtin module rather than a separately built > extension module. I have another unpleasant but slightly less hacky solution. We put detect_encoding in linecache where it is actually used. -- Regards, Benjamin From python-checkins at python.org Sun Nov 15 07:10:31 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 06:10:31 -0000 Subject: [Python-checkins] r76282 - python/trunk/Lib/urllib2.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 07:10:30 2009 New Revision: 76282 Log: Addition of some details in the code comments. Modified: python/trunk/Lib/urllib2.py Modified: python/trunk/Lib/urllib2.py ============================================================================== --- python/trunk/Lib/urllib2.py (original) +++ python/trunk/Lib/urllib2.py Sun Nov 15 07:10:30 2009 @@ -30,7 +30,9 @@ install_opener -- Installs a new opener as the default opener. objects of interest: -OpenerDirector -- + +OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages +the Handler classes, while dealing with requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP @@ -440,7 +442,7 @@ """Create an opener object from a list of handlers. The opener will use several default handlers, including support - for HTTP and FTP. + for HTTP, FTP and when applicable, HTTPS. If any of the handlers passed as arguments are subclasses of the default handlers, the default handlers will not be used. From python-checkins at python.org Sun Nov 15 07:14:36 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 06:14:36 -0000 Subject: [Python-checkins] r76283 - in python/branches/release26-maint: Lib/urllib2.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 07:14:36 2009 New Revision: 76283 Log: Merged revisions 76282 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76282 | senthil.kumaran | 2009-11-15 11:40:30 +0530 (Sun, 15 Nov 2009) | 3 lines Addition of some details in the code comments. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/urllib2.py Modified: python/branches/release26-maint/Lib/urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/urllib2.py (original) +++ python/branches/release26-maint/Lib/urllib2.py Sun Nov 15 07:14:36 2009 @@ -30,7 +30,9 @@ install_opener -- Installs a new opener as the default opener. objects of interest: -OpenerDirector -- + +OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages +the Handler classes, while dealing with requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP @@ -440,7 +442,7 @@ """Create an opener object from a list of handlers. The opener will use several default handlers, including support - for HTTP and FTP. + for HTTP, FTP and when applicable, HTTPS. If any of the handlers passed as arguments are subclasses of the default handlers, the default handlers will not be used. From python-checkins at python.org Sun Nov 15 07:20:55 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 06:20:55 -0000 Subject: [Python-checkins] r76284 - in python/branches/py3k: Lib/urllib/request.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 07:20:55 2009 New Revision: 76284 Log: Merged revisions 76282 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76282 | senthil.kumaran | 2009-11-15 11:40:30 +0530 (Sun, 15 Nov 2009) | 3 lines Addition of some details in the code comments. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/urllib/request.py Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Sun Nov 15 07:20:55 2009 @@ -30,7 +30,9 @@ install_opener -- Installs a new opener as the default opener. objects of interest: -OpenerDirector -- + +OpenerDirector -- Sets up the User-Agent as the Python-urllib and manages the +Handler classes while dealing with both requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP @@ -398,7 +400,7 @@ """Create an opener object from a list of handlers. The opener will use several default handlers, including support - for HTTP and FTP. + for HTTP, FTP and when applicable HTTPS. If any of the handlers passed as arguments are subclasses of the default handlers, the default handlers will not be used. From python-checkins at python.org Sun Nov 15 08:27:02 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 07:27:02 -0000 Subject: [Python-checkins] r76285 - in python/branches/release31-maint: Lib/urllib/request.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 08:27:02 2009 New Revision: 76285 Log: Merged revisions 76284 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76284 | senthil.kumaran | 2009-11-15 11:50:55 +0530 (Sun, 15 Nov 2009) | 9 lines Merged revisions 76282 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76282 | senthil.kumaran | 2009-11-15 11:40:30 +0530 (Sun, 15 Nov 2009) | 3 lines Addition of some details in the code comments. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/urllib/request.py Modified: python/branches/release31-maint/Lib/urllib/request.py ============================================================================== --- python/branches/release31-maint/Lib/urllib/request.py (original) +++ python/branches/release31-maint/Lib/urllib/request.py Sun Nov 15 08:27:02 2009 @@ -30,7 +30,9 @@ install_opener -- Installs a new opener as the default opener. objects of interest: -OpenerDirector -- + +OpenerDirector -- Sets up the User-Agent as the Python-urllib and manages the +Handler classes while dealing with both requests and responses. Request -- An object that encapsulates the state of a request. The state can be as simple as the URL. It can also include extra HTTP @@ -398,7 +400,7 @@ """Create an opener object from a list of handlers. The opener will use several default handlers, including support - for HTTP and FTP. + for HTTP, FTP and when applicable HTTPS. If any of the handlers passed as arguments are subclasses of the default handlers, the default handlers will not be used. From python-checkins at python.org Sun Nov 15 08:30:34 2009 From: python-checkins at python.org (nick.coghlan) Date: Sun, 15 Nov 2009 07:30:34 -0000 Subject: [Python-checkins] r76286 - in python/trunk: Doc/library/runpy.rst Lib/runpy.py Lib/test/script_helper.py Lib/test/test_cmd_line.py Lib/test/test_cmd_line_script.py Lib/test/test_runpy.py Lib/test/test_zipimport_support.py Misc/NEWS Message-ID: Author: nick.coghlan Date: Sun Nov 15 08:30:34 2009 New Revision: 76286 Log: Issue #6816: expose the zipfile and directory execution mechanism to Python code via the runpy module. Also consolidated some script execution functionality in the test harness into a helper module and removed some implementation details from the runpy module documentation. Added: python/trunk/Lib/test/script_helper.py (contents, props changed) Modified: python/trunk/Doc/library/runpy.rst python/trunk/Lib/runpy.py python/trunk/Lib/test/test_cmd_line.py python/trunk/Lib/test/test_cmd_line_script.py python/trunk/Lib/test/test_runpy.py python/trunk/Lib/test/test_zipimport_support.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/runpy.rst ============================================================================== --- python/trunk/Doc/library/runpy.rst (original) +++ python/trunk/Doc/library/runpy.rst Sun Nov 15 08:30:34 2009 @@ -9,70 +9,122 @@ .. versionadded:: 2.5 The :mod:`runpy` module is used to locate and run Python modules without -importing them first. Its main use is to implement the :option:`-m` command line -switch that allows scripts to be located using the Python module namespace -rather than the filesystem. +importing them first. Its main use is to implement the :option:`-m` command +line switch that allows scripts to be located using the Python module +namespace rather than the filesystem. -When executed as a script, the module effectively operates as follows:: +The :mod:`runpy` module provides two functions: - del sys.argv[0] # Remove the runpy module from the arguments - run_module(sys.argv[0], run_name="__main__", alter_sys=True) -The :mod:`runpy` module provides a single function: +.. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) + Execute the code of the specified module and return the resulting module + globals dictionary. The module's code is first located using the standard + import mechanism (refer to PEP 302 for details) and then executed in a + fresh module namespace. -.. function:: run_module(mod_name[, init_globals] [, run_name][, alter_sys]) + If the supplied module name refers to a package rather than a normal + module, then that package is imported and the ``__main__`` submodule within + that package is then executed and the resulting module globals dictionary + returned. - Execute the code of the specified module and return the resulting module globals - dictionary. The module's code is first located using the standard import - mechanism (refer to PEP 302 for details) and then executed in a fresh module - namespace. + The optional dictionary argument *init_globals* may be used to pre-populate + the module's globals dictionary before the code is executed. The supplied + dictionary will not be modified. If any of the special global variables + below are defined in the supplied dictionary, those definitions are + overridden by :func:`run_module`. - If the supplied module name refers to a package rather than a normal module, - then that package is imported and the ``__main__`` submodule within that - package is then executed and the resulting module globals dictionary returned. + The special global variables ``__name__``, ``__file__``, ``__loader__`` + and ``__package__`` are set in the globals dictionary before the module + code is executed (Note that this is a minimal set of variables - other + variables may be set implicitly as an interpreter implementation detail). - The optional dictionary argument *init_globals* may be used to pre-populate the - globals dictionary before the code is executed. The supplied dictionary will not - be modified. If any of the special global variables below are defined in the - supplied dictionary, those definitions are overridden by the ``run_module`` - function. + ``__name__`` is set to *run_name* if this optional argument is not + :const:`None`, to ``mod_name + '.__main__'`` if the named module is a + package and to the *mod_name* argument otherwise. - The special global variables ``__name__``, ``__file__``, ``__loader__``, - ``__builtins__`` and ``__package__`` are set in the globals dictionary before - the module code is executed. + ``__file__`` is set to the name provided by the module loader. If the + loader does not make filename information available, this variable is set + to `:const:`None`. - ``__name__`` is set to *run_name* if this optional argument is supplied, to - ``mod_name + '.__main__'`` if the named module is a package and to the - *mod_name* argument otherwise. + ``__loader__`` is set to the PEP 302 module loader used to retrieve the + code for the module (This loader may be a wrapper around the standard + import mechanism). - ``__loader__`` is set to the PEP 302 module loader used to retrieve the code for - the module (This loader may be a wrapper around the standard import mechanism). + ``__package__`` is set to *mod_name* if the named module is a package and + to ``mod_name.rpartition('.')[0]`` otherwise. - ``__file__`` is set to the name provided by the module loader. If the loader - does not make filename information available, this variable is set to ``None``. - - ``__builtins__`` is automatically initialised with a reference to the top level - namespace of the :mod:`__builtin__` module. - - ``__package__`` is set to *mod_name* if the named module is a package and to - ``mod_name.rpartition('.')[0]`` otherwise. - - If the argument *alter_sys* is supplied and evaluates to ``True``, then - ``sys.argv[0]`` is updated with the value of ``__file__`` and + If the argument *alter_sys* is supplied and evaluates to :const:`True`, + then ``sys.argv[0]`` is updated with the value of ``__file__`` and ``sys.modules[__name__]`` is updated with a temporary module object for the module being executed. Both ``sys.argv[0]`` and ``sys.modules[__name__]`` are restored to their original values before the function returns. - Note that this manipulation of :mod:`sys` is not thread-safe. Other threads may - see the partially initialised module, as well as the altered list of arguments. - It is recommended that the :mod:`sys` module be left alone when invoking this - function from threaded code. + Note that this manipulation of :mod:`sys` is not thread-safe. Other threads + may see the partially initialised module, as well as the altered list of + arguments. It is recommended that the :mod:`sys` module be left alone when + invoking this function from threaded code. .. versionchanged:: 2.7 - Added ability to execute packages by looking for a ``__main__`` submodule + Added ability to execute packages by looking for a ``__main__`` + submodule + + +.. function:: run_path(file_path, init_globals=None, run_name=None) + + Execute the code at the named filesystem location and return the resulting + module globals dictionary. As with a script name supplied to the CPython + command line, the supplied path may refer to a Python source file, a + compiled bytecode file or a valid sys.path entry containing a ``__main__`` + module (e.g. a zipfile containing a top-level ``__main__.py`` file). + + For a simple script, the specified code is simply executed in a fresh + module namespace. For a valid sys.path entry (typically a zipfile or + directory), the entry is first added to the beginning of ``sys.path``. The + function then looks for and executes a :mod:`__main__` module using the + updated path. Note that there is no special protection against invoking + an existing :mod:`__main__` entry located elsewhere on ``sys.path`` if + there is no such module at the specified location. + + The optional dictionary argument *init_globals* may be used to pre-populate + the module's globals dictionary before the code is executed. The supplied + dictionary will not be modified. If any of the special global variables + below are defined in the supplied dictionary, those definitions are + overridden by :func:`run_path`. + + The special global variables ``__name__``, ``__file__``, ``__loader__`` + and ``__package__`` are set in the globals dictionary before the module + code is executed (Note that this is a minimal set of variables - other + variables may be set implicitly as an interpreter implementation detail). + + ``__name__`` is set to *run_name* if this optional argument is not + :const:`None` and to ``''`` otherwise. + + ``__file__`` is set to the name provided by the module loader. If the + loader does not make filename information available, this variable is set + to :const:`None`. For a simple script, this will be set to ``file_path``. + + ``__loader__`` is set to the PEP 302 module loader used to retrieve the + code for the module (This loader may be a wrapper around the standard + import mechanism). For a simple script, this will be set to :const:`None`. + + ``__package__`` is set to ``__name__.rpartition('.')[0]``. + + A number of alterations are also made to the :mod:`sys` module. Firstly, + ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated + with the value of ``file_path`` and ``sys.modules[__name__]`` is updated + with a temporary module object for the module being executed. All + modifications to items in :mod:`sys` are reverted before the function + returns. + + Note that, unlike :func:`run_module`, the alterations made to :mod:`sys` + are not optional in this function as these adjustments are essential to + allowing the execution of sys.path entries. As the thread safety + limitations still apply, use of this function in threaded code should be + either serialised with the import lock or delegated to a separate process. + .. versionadded:: 2.7 .. seealso:: @@ -82,3 +134,4 @@ :pep:`366` - Main module explicit relative imports PEP written and implemented by Nick Coghlan. + :ref:`using-on-general` - CPython command line details Modified: python/trunk/Lib/runpy.py ============================================================================== --- python/trunk/Lib/runpy.py (original) +++ python/trunk/Lib/runpy.py Sun Nov 15 08:30:34 2009 @@ -11,15 +11,53 @@ import sys import imp +from pkgutil import read_code try: from imp import get_loader except ImportError: from pkgutil import get_loader __all__ = [ - "run_module", + "run_module", "run_path", ] +class _TempModule(object): + """Temporarily replace a module in sys.modules with an empty namespace""" + def __init__(self, mod_name): + self.mod_name = mod_name + self.module = imp.new_module(mod_name) + self._saved_module = [] + + def __enter__(self): + mod_name = self.mod_name + try: + self._saved_module.append(sys.modules[mod_name]) + except KeyError: + pass + sys.modules[mod_name] = self.module + return self + + def __exit__(self, *args): + if self._saved_module: + sys.modules[self.mod_name] = self._saved_module[0] + else: + del sys.modules[self.mod_name] + self._saved_module = [] + +class _ModifiedArgv0(object): + def __init__(self, value): + self.value = value + self._saved_value = self._sentinel = object() + + def __enter__(self): + if self._saved_value is not self._sentinel: + raise RuntimeError("Already preserving saved value") + self._saved_value = sys.argv[0] + sys.argv[0] = self.value + + def __exit__(self, *args): + self.value = self._sentinel + sys.argv[0] = self._saved_value def _run_code(code, run_globals, init_globals=None, mod_name=None, mod_fname=None, @@ -38,26 +76,10 @@ mod_name=None, mod_fname=None, mod_loader=None, pkg_name=None): """Helper to run code in new namespace with sys modified""" - # Set up the top level namespace dictionary - temp_module = imp.new_module(mod_name) - mod_globals = temp_module.__dict__ - # Modify sys.argv[0] and sys.module[mod_name] - saved_argv0 = sys.argv[0] - restore_module = mod_name in sys.modules - if restore_module: - saved_module = sys.modules[mod_name] - sys.argv[0] = mod_fname - sys.modules[mod_name] = temp_module - try: + with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname): + mod_globals = temp_module.module.__dict__ _run_code(code, mod_globals, init_globals, - mod_name, mod_fname, - mod_loader, pkg_name) - finally: - sys.argv[0] = saved_argv0 - if restore_module: - sys.modules[mod_name] = saved_module - else: - del sys.modules[mod_name] + mod_name, mod_fname, mod_loader, pkg_name) # Copy the globals of the temporary module, as they # may be cleared when the temporary module goes away return mod_globals.copy() @@ -95,10 +117,22 @@ return mod_name, loader, code, filename -# XXX ncoghlan: Should this be documented and made public? -# (Current thoughts: don't repeat the mistake that lead to its -# creation when run_module() no longer met the needs of -# mainmodule.c, but couldn't be changed because it was public) +def _get_main_module_details(): + # Helper that gives a nicer error message when attempting to + # execute a zipfile or directory by invoking __main__.py + main_name = "__main__" + try: + return _get_module_details(main_name) + except ImportError as exc: + if main_name in str(exc): + raise ImportError("can't find %r module in %r" % + (main_name, sys.path[0])) + raise + +# This function is the actual implementation of the -m switch and direct +# execution of zipfiles and directories and is deliberately kept private. +# This avoids a repeat of the situation where run_module() no longer met the +# needs of mainmodule.c, but couldn't be changed because it was public def _run_module_as_main(mod_name, alter_argv=True): """Runs the designated module in the __main__ namespace @@ -113,18 +147,12 @@ __package__ """ try: - mod_name, loader, code, fname = _get_module_details(mod_name) + if alter_argv or mod_name != "__main__": # i.e. -m switch + mod_name, loader, code, fname = _get_module_details(mod_name) + else: # i.e. directory or zipfile execution + mod_name, loader, code, fname = _get_main_module_details() except ImportError as exc: - # Try to provide a good error message - # for directories, zip files and the -m switch - if alter_argv: - # For -m switch, just display the exception - info = str(exc) - else: - # For directories/zipfiles, let the user - # know what the code was looking for - info = "can't find '__main__.py' in %r" % sys.argv[0] - msg = "%s: %s" % (sys.executable, info) + msg = "%s: %s" % (sys.executable, str(exc)) sys.exit(msg) pkg_name = mod_name.rpartition('.')[0] main_globals = sys.modules["__main__"].__dict__ @@ -152,6 +180,95 @@ fname, loader, pkg_name) +# XXX (ncoghlan): Perhaps expose the C API function +# as imp.get_importer instead of reimplementing it in Python? +def _get_importer(path_name): + """Python version of PyImport_GetImporter C API function""" + cache = sys.path_importer_cache + try: + importer = cache[path_name] + except KeyError: + # Not yet cached. Flag as using the + # standard machinery until we finish + # checking the hooks + cache[path_name] = None + for hook in sys.path_hooks: + try: + importer = hook(path_name) + break + except ImportError: + pass + else: + # The following check looks a bit odd. The trick is that + # NullImporter throws ImportError if the supplied path is a + # *valid* directory entry (and hence able to be handled + # by the standard import machinery) + try: + importer = imp.NullImporter(path_name) + except ImportError: + return None + cache[path_name] = importer + return importer + +def _get_code_from_file(fname): + # Check for a compiled file first + with open(fname, "rb") as f: + code = read_code(f) + if code is None: + # That didn't work, so try it as normal source code + with open(fname, "rU") as f: + code = compile(f.read(), fname, 'exec') + return code + +def run_path(path_name, init_globals=None, run_name=None): + """Execute code located at the specified filesystem location + + Returns the resulting top level namespace dictionary + + The file path may refer directly to a Python script (i.e. + one that could be directly executed with execfile) or else + it may refer to a zipfile or directory containing a top + level __main__.py script. + """ + if run_name is None: + run_name = "" + importer = _get_importer(path_name) + if isinstance(importer, imp.NullImporter): + # Not a valid sys.path entry, so run the code directly + # execfile() doesn't help as we want to allow compiled files + code = _get_code_from_file(path_name) + return _run_module_code(code, init_globals, run_name, path_name) + else: + # Importer is defined for path, so add it to + # the start of sys.path + sys.path.insert(0, path_name) + try: + # Here's where things are a little different from the run_module + # case. There, we only had to replace the module in sys while the + # code was running and doing so was somewhat optional. Here, we + # have no choice and we have to remove it even while we read the + # code. If we don't do this, a __loader__ attribute in the + # existing __main__ module may prevent location of the new module. + main_name = "__main__" + saved_main = sys.modules[main_name] + del sys.modules[main_name] + try: + mod_name, loader, code, fname = _get_main_module_details() + finally: + sys.modules[main_name] = saved_main + pkg_name = "" + with _TempModule(run_name) as temp_module, \ + _ModifiedArgv0(path_name): + mod_globals = temp_module.module.__dict__ + return _run_code(code, mod_globals, init_globals, + run_name, fname, loader, pkg_name) + finally: + try: + sys.path.remove(path_name) + except ValueError: + pass + + if __name__ == "__main__": # Run the module specified as the next command line argument if len(sys.argv) < 2: Added: python/trunk/Lib/test/script_helper.py ============================================================================== --- (empty file) +++ python/trunk/Lib/test/script_helper.py Sun Nov 15 08:30:34 2009 @@ -0,0 +1,119 @@ +# Common utility functions used by various script execution tests +# e.g. test_cmd_line, test_cmd_line_script and test_runpy + +import sys +import os +import os.path +import tempfile +import subprocess +import py_compile +import contextlib +import shutil +import zipfile + +# Executing the interpreter in a subprocess +def python_exit_code(*args): + cmd_line = [sys.executable, '-E'] + cmd_line.extend(args) + with open(os.devnull, 'w') as devnull: + return subprocess.call(cmd_line, stdout=devnull, + stderr=subprocess.STDOUT) + +def spawn_python(*args): + cmd_line = [sys.executable, '-E'] + cmd_line.extend(args) + return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + +def kill_python(p): + p.stdin.close() + data = p.stdout.read() + p.stdout.close() + # try to cleanup the child so we don't appear to leak when running + # with regrtest -R. This should be a no-op on Windows. + subprocess._cleanup() + return data + +def run_python(*args): + if __debug__: + p = spawn_python(*args) + else: + p = spawn_python('-O', *args) + stdout_data = kill_python(p) + return p.wait(), stdout_data + +# Script creation utilities + at contextlib.contextmanager +def temp_dir(): + dirname = tempfile.mkdtemp() + dirname = os.path.realpath(dirname) + try: + yield dirname + finally: + shutil.rmtree(dirname) + +def make_script(script_dir, script_basename, source): + script_filename = script_basename+os.extsep+'py' + script_name = os.path.join(script_dir, script_filename) + script_file = open(script_name, 'w') + script_file.write(source) + script_file.close() + return script_name + +def compile_script(script_name): + py_compile.compile(script_name, doraise=True) + if __debug__: + compiled_name = script_name + 'c' + else: + compiled_name = script_name + 'o' + return compiled_name + +def make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None): + zip_filename = zip_basename+os.extsep+'zip' + zip_name = os.path.join(zip_dir, zip_filename) + zip_file = zipfile.ZipFile(zip_name, 'w') + if name_in_zip is None: + name_in_zip = os.path.basename(script_name) + zip_file.write(script_name, name_in_zip) + zip_file.close() + #if test.test_support.verbose: + # zip_file = zipfile.ZipFile(zip_name, 'r') + # print 'Contents of %r:' % zip_name + # zip_file.printdir() + # zip_file.close() + return zip_name, os.path.join(zip_name, name_in_zip) + +def make_pkg(pkg_dir): + os.mkdir(pkg_dir) + make_script(pkg_dir, '__init__', '') + +def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth=1, compiled=False): + unlink = [] + init_name = make_script(zip_dir, '__init__', '') + unlink.append(init_name) + init_basename = os.path.basename(init_name) + script_name = make_script(zip_dir, script_basename, source) + unlink.append(script_name) + if compiled: + init_name = compile_script(init_name) + script_name = compile_script(script_name) + unlink.extend((init_name, script_name)) + pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] + script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) + zip_filename = zip_basename+os.extsep+'zip' + zip_name = os.path.join(zip_dir, zip_filename) + zip_file = zipfile.ZipFile(zip_name, 'w') + for name in pkg_names: + init_name_in_zip = os.path.join(name, init_basename) + zip_file.write(init_name, init_name_in_zip) + zip_file.write(script_name, script_name_in_zip) + zip_file.close() + for name in unlink: + os.unlink(name) + #if test.test_support.verbose: + # zip_file = zipfile.ZipFile(zip_name, 'r') + # print 'Contents of %r:' % zip_name + # zip_file.printdir() + # zip_file.close() + return zip_name, os.path.join(zip_name, script_name_in_zip) Modified: python/trunk/Lib/test/test_cmd_line.py ============================================================================== --- python/trunk/Lib/test/test_cmd_line.py (original) +++ python/trunk/Lib/test/test_cmd_line.py Sun Nov 15 08:30:34 2009 @@ -5,34 +5,16 @@ import os import test.test_support, unittest import sys -import subprocess +from test.script_helper import spawn_python, kill_python, python_exit_code -def _spawn_python(*args): - cmd_line = [sys.executable, '-E'] - cmd_line.extend(args) - return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - -def _kill_python(p): - p.stdin.close() - data = p.stdout.read() - p.stdout.close() - # try to cleanup the child so we don't appear to leak when running - # with regrtest -R. This should be a no-op on Windows. - subprocess._cleanup() - return data class CmdLineTest(unittest.TestCase): def start_python(self, *args): - p = _spawn_python(*args) - return _kill_python(p) + p = spawn_python(*args) + return kill_python(p) def exit_code(self, *args): - cmd_line = [sys.executable, '-E'] - cmd_line.extend(args) - with open(os.devnull, 'w') as devnull: - return subprocess.call(cmd_line, stdout=devnull, - stderr=subprocess.STDOUT) + return python_exit_code(*args) def test_directories(self): self.assertNotEqual(self.exit_code('.'), 0) @@ -85,10 +67,10 @@ # -m and -i need to play well together # Runs the timeit module and checks the __main__ # namespace has been populated appropriately - p = _spawn_python('-i', '-m', 'timeit', '-n', '1') + p = spawn_python('-i', '-m', 'timeit', '-n', '1') p.stdin.write('Timer\n') p.stdin.write('exit()\n') - data = _kill_python(p) + data = kill_python(p) self.assertTrue(data.startswith('1 loop')) self.assertTrue('__main__.Timer' in data) Modified: python/trunk/Lib/test/test_cmd_line_script.py ============================================================================== --- python/trunk/Lib/test/test_cmd_line_script.py (original) +++ python/trunk/Lib/test/test_cmd_line_script.py Sun Nov 15 08:30:34 2009 @@ -5,34 +5,12 @@ import os.path import sys import test.test_support -import tempfile -import subprocess -import py_compile -import contextlib -import shutil -import zipfile +from test.script_helper import (spawn_python, kill_python, run_python, + temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) verbose = test.test_support.verbose -# XXX ncoghlan: Should we consider moving these to test_support? -from test_cmd_line import _spawn_python, _kill_python - -def _run_python(*args): - if __debug__: - p = _spawn_python(*args) - else: - p = _spawn_python('-O', *args) - stdout_data = _kill_python(p) - return p.wait(), stdout_data - - at contextlib.contextmanager -def temp_dir(): - dirname = tempfile.mkdtemp() - dirname = os.path.realpath(dirname) - try: - yield dirname - finally: - shutil.rmtree(dirname) test_source = """\ # Script may be run with optimisation enabled, so don't rely on assert @@ -60,63 +38,12 @@ """ def _make_test_script(script_dir, script_basename, source=test_source): - script_filename = script_basename+os.extsep+'py' - script_name = os.path.join(script_dir, script_filename) - script_file = open(script_name, 'w') - script_file.write(source) - script_file.close() - return script_name - -def _compile_test_script(script_name): - py_compile.compile(script_name, doraise=True) - if __debug__: - compiled_name = script_name + 'c' - else: - compiled_name = script_name + 'o' - return compiled_name - -def _make_test_zip(zip_dir, zip_basename, script_name, name_in_zip=None): - zip_filename = zip_basename+os.extsep+'zip' - zip_name = os.path.join(zip_dir, zip_filename) - zip_file = zipfile.ZipFile(zip_name, 'w') - if name_in_zip is None: - name_in_zip = os.path.basename(script_name) - zip_file.write(script_name, name_in_zip) - zip_file.close() - #if verbose: - # zip_file = zipfile.ZipFile(zip_name, 'r') - # print 'Contents of %r:' % zip_name - # zip_file.printdir() - # zip_file.close() - return zip_name, os.path.join(zip_name, name_in_zip) - -def _make_test_pkg(pkg_dir): - os.mkdir(pkg_dir) - _make_test_script(pkg_dir, '__init__', '') + return make_script(script_dir, script_basename, source) def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source=test_source, depth=1): - init_name = _make_test_script(zip_dir, '__init__', '') - init_basename = os.path.basename(init_name) - script_name = _make_test_script(zip_dir, script_basename, source) - pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] - script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) - zip_filename = zip_basename+os.extsep+'zip' - zip_name = os.path.join(zip_dir, zip_filename) - zip_file = zipfile.ZipFile(zip_name, 'w') - for name in pkg_names: - init_name_in_zip = os.path.join(name, init_basename) - zip_file.write(init_name, init_name_in_zip) - zip_file.write(script_name, script_name_in_zip) - zip_file.close() - os.unlink(init_name) - os.unlink(script_name) - #if verbose: - # zip_file = zipfile.ZipFile(zip_name, 'r') - # print 'Contents of %r:' % zip_name - # zip_file.printdir() - # zip_file.close() - return zip_name, os.path.join(zip_name, script_name_in_zip) + return make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth) # There's no easy way to pass the script directory in to get # -m to work (avoiding that is the whole point of making @@ -134,14 +61,14 @@ else: path = repr(path) source = launch_source % (path, module_name) - return _make_test_script(script_dir, script_basename, source) + return make_script(script_dir, script_basename, source) class CmdLineTest(unittest.TestCase): def _check_script(self, script_name, expected_file, expected_argv0, expected_package, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) - exit_code, data = _run_python(*run_args) + exit_code, data = run_python(*run_args) if verbose: print 'Output from test script %r:' % script_name print data @@ -161,7 +88,7 @@ def _check_import_error(self, script_name, expected_msg, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) - exit_code, data = _run_python(*run_args) + exit_code, data = run_python(*run_args) if verbose: print 'Output from test script %r:' % script_name print data @@ -176,7 +103,7 @@ def test_script_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) self._check_script(compiled_name, compiled_name, compiled_name, None) @@ -188,39 +115,39 @@ def test_directory_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) self._check_script(script_dir, compiled_name, script_dir, '') def test_directory_error(self): with temp_dir() as script_dir: - msg = "can't find '__main__.py' in %r" % script_dir + msg = "can't find '__main__' module in %r" % script_dir self._check_import_error(script_dir, msg) def test_zipfile(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', script_name) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) self._check_script(zip_name, run_name, zip_name, '') def test_zipfile_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = _compile_test_script(script_name) - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', compiled_name) + compiled_name = compile_script(script_name) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, run_name, zip_name, '') def test_zipfile_error(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'not_main') - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', script_name) - msg = "can't find '__main__.py' in %r" % zip_name + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) + msg = "can't find '__main__' module in %r" % zip_name self._check_import_error(zip_name, msg) def test_module_in_package(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, 'script') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script') self._check_script(launch_name, script_name, script_name, 'test_pkg') @@ -240,7 +167,7 @@ def test_package(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name, script_name, @@ -249,9 +176,9 @@ def test_package_compiled(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name, compiled_name, @@ -260,7 +187,7 @@ def test_package_error(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) msg = ("'test_pkg' is a package and cannot " "be directly executed") launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') @@ -269,9 +196,9 @@ def test_package_recursion(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) main_dir = os.path.join(pkg_dir, '__main__') - _make_test_pkg(main_dir) + make_pkg(main_dir) msg = ("Cannot use package as __main__ module; " "'test_pkg' is a package and cannot " "be directly executed") Modified: python/trunk/Lib/test/test_runpy.py ============================================================================== --- python/trunk/Lib/test/test_runpy.py (original) +++ python/trunk/Lib/test/test_runpy.py Sun Nov 15 08:30:34 2009 @@ -5,8 +5,11 @@ import sys import tempfile from test.test_support import verbose, run_unittest, forget -from runpy import _run_code, _run_module_code, run_module +from test.script_helper import (temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) + +from runpy import _run_code, _run_module_code, run_module, run_path # Note: This module can't safely test _run_module_as_main as it # runs its tests in the current process, which would mess with the # real __main__ module (usually test.regrtest) @@ -15,6 +18,7 @@ # Set up the test code and expected results class RunModuleCodeTest(unittest.TestCase): + """Unit tests for runpy._run_code and runpy._run_module_code""" expected_result = ["Top level assignment", "Lower level reference"] test_source = ( @@ -37,14 +41,14 @@ def test_run_code(self): saved_argv0 = sys.argv[0] d = _run_code(self.test_source, {}) - self.assertTrue(d["result"] == self.expected_result) - self.assertTrue(d["__name__"] is None) - self.assertTrue(d["__file__"] is None) - self.assertTrue(d["__loader__"] is None) - self.assertTrue(d["__package__"] is None) - self.assertTrue(d["run_argv0"] is saved_argv0) - self.assertTrue("run_name" not in d) - self.assertTrue(sys.argv[0] is saved_argv0) + self.assertEqual(d["result"], self.expected_result) + self.assertIs(d["__name__"], None) + self.assertIs(d["__file__"], None) + self.assertIs(d["__loader__"], None) + self.assertIs(d["__package__"], None) + self.assertIs(d["run_argv0"], saved_argv0) + self.assertNotIn("run_name", d) + self.assertIs(sys.argv[0], saved_argv0) def test_run_module_code(self): initial = object() @@ -60,22 +64,23 @@ file, loader, package) - self.assertTrue("result" not in d1) - self.assertTrue(d2["initial"] is initial) - self.assertTrue(d2["result"] == self.expected_result) - self.assertTrue(d2["nested"]["x"] == 1) - self.assertTrue(d2["__name__"] is name) + self.assertNotIn("result", d1) + self.assertIs(d2["initial"], initial) + self.assertEqual(d2["result"], self.expected_result) + self.assertEqual(d2["nested"]["x"], 1) + self.assertIs(d2["__name__"], name) self.assertTrue(d2["run_name_in_sys_modules"]) self.assertTrue(d2["module_in_sys_modules"]) - self.assertTrue(d2["__file__"] is file) - self.assertTrue(d2["run_argv0"] is file) - self.assertTrue(d2["__loader__"] is loader) - self.assertTrue(d2["__package__"] is package) - self.assertTrue(sys.argv[0] is saved_argv0) - self.assertTrue(name not in sys.modules) + self.assertIs(d2["__file__"], file) + self.assertIs(d2["run_argv0"], file) + self.assertIs(d2["__loader__"], loader) + self.assertIs(d2["__package__"], package) + self.assertIs(sys.argv[0], saved_argv0) + self.assertNotIn(name, sys.modules) class RunModuleTest(unittest.TestCase): + """Unit tests for runpy.run_module""" def expect_import_error(self, mod_name): try: @@ -272,9 +277,124 @@ self._check_relative_imports(depth, "__main__") +class RunPathTest(unittest.TestCase): + """Unit tests for runpy.run_path""" + # Based on corresponding tests in test_cmd_line_script + + test_source = """\ +# Script may be run with optimisation enabled, so don't rely on assert +# statements being executed +def assertEqual(lhs, rhs): + if lhs != rhs: + raise AssertionError('%r != %r' % (lhs, rhs)) +def assertIs(lhs, rhs): + if lhs is not rhs: + raise AssertionError('%r is not %r' % (lhs, rhs)) +# Check basic code execution +result = ['Top level assignment'] +def f(): + result.append('Lower level reference') +f() +assertEqual(result, ['Top level assignment', 'Lower level reference']) +# Check the sys module +import sys +assertIs(globals(), sys.modules[__name__].__dict__) +argv0 = sys.argv[0] +""" + + def _make_test_script(self, script_dir, script_basename, source=None): + if source is None: + source = self.test_source + return make_script(script_dir, script_basename, source) + + def _check_script(self, script_name, expected_name, expected_file, + expected_argv0, expected_package): + result = run_path(script_name) + self.assertEqual(result["__name__"], expected_name) + self.assertEqual(result["__file__"], expected_file) + self.assertIn("argv0", result) + self.assertEqual(result["argv0"], expected_argv0) + self.assertEqual(result["__package__"], expected_package) + + def _check_import_error(self, script_name, msg): + self.assertRaisesRegexp(ImportError, msg, run_path, script_name) + + def test_basic_script(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name) + self._check_script(script_name, "", script_name, + script_name, None) + + def test_script_compiled(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + os.remove(script_name) + self._check_script(compiled_name, "", compiled_name, + compiled_name, None) + + def test_directory(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + self._check_script(script_dir, "", script_name, + script_dir, '') + + def test_directory_compiled(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + os.remove(script_name) + self._check_script(script_dir, "", compiled_name, + script_dir, '') + + def test_directory_error(self): + with temp_dir() as script_dir: + mod_name = 'not_main' + script_name = self._make_test_script(script_dir, mod_name) + msg = "can't find '__main__' module in %r" % script_dir + self._check_import_error(script_dir, msg) + + def test_zipfile(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + self._check_script(zip_name, "", fname, zip_name, '') + + def test_zipfile_compiled(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', compiled_name) + self._check_script(zip_name, "", fname, zip_name, '') + + def test_zipfile_error(self): + with temp_dir() as script_dir: + mod_name = 'not_main' + script_name = self._make_test_script(script_dir, mod_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + msg = "can't find '__main__' module in %r" % zip_name + self._check_import_error(zip_name, msg) + + def test_main_recursion_error(self): + with temp_dir() as script_dir, temp_dir() as dummy_dir: + mod_name = '__main__' + source = ("import runpy\n" + "runpy.run_path(%r)\n") % dummy_dir + script_name = self._make_test_script(script_dir, mod_name, source) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + msg = "recursion depth exceeded" + self.assertRaisesRegexp(RuntimeError, msg, run_path, zip_name) + + + def test_main(): - run_unittest(RunModuleCodeTest) - run_unittest(RunModuleTest) + run_unittest(RunModuleCodeTest, RunModuleTest, RunPathTest) if __name__ == "__main__": test_main() Modified: python/trunk/Lib/test/test_zipimport_support.py ============================================================================== --- python/trunk/Lib/test/test_zipimport_support.py (original) +++ python/trunk/Lib/test/test_zipimport_support.py Sun Nov 15 08:30:34 2009 @@ -14,6 +14,9 @@ import inspect import linecache import pdb +from test.script_helper import (spawn_python, kill_python, run_python, + temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) verbose = test.test_support.verbose @@ -29,11 +32,6 @@ # Retrieve some helpers from other test cases from test import test_doctest, sample_doctest from test.test_importhooks import ImportHooksBaseTestCase -from test.test_cmd_line_script import temp_dir, _run_python, \ - _spawn_python, _kill_python, \ - _make_test_script, \ - _compile_test_script, \ - _make_test_zip, _make_test_pkg def _run_object_doctest(obj, module): @@ -78,10 +76,10 @@ def test_inspect_getsource_issue4223(self): test_src = "def foo(): pass\n" with temp_dir() as d: - init_name = _make_test_script(d, '__init__', test_src) + init_name = make_script(d, '__init__', test_src) name_in_zip = os.path.join('zip_pkg', os.path.basename(init_name)) - zip_name, run_name = _make_test_zip(d, 'test_zip', + zip_name, run_name = make_zip_script(d, 'test_zip', init_name, name_in_zip) os.remove(init_name) sys.path.insert(0, zip_name) @@ -106,9 +104,9 @@ sample_src = sample_src.replace("test.test_doctest", "test_zipped_doctest") with temp_dir() as d: - script_name = _make_test_script(d, 'test_zipped_doctest', + script_name = make_script(d, 'test_zipped_doctest', test_src) - zip_name, run_name = _make_test_zip(d, 'test_zip', + zip_name, run_name = make_zip_script(d, 'test_zip', script_name) z = zipfile.ZipFile(zip_name, 'a') z.writestr("sample_zipped_doctest.py", sample_src) @@ -184,17 +182,17 @@ """) pattern = 'File "%s", line 2, in %s' with temp_dir() as d: - script_name = _make_test_script(d, 'script', test_src) - exit_code, data = _run_python(script_name) + script_name = make_script(d, 'script', test_src) + exit_code, data = run_python(script_name) expected = pattern % (script_name, "__main__.Test") if verbose: print "Expected line", expected print "Got stdout:" print data self.assertTrue(expected in data) - zip_name, run_name = _make_test_zip(d, "test_zip", + zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') - exit_code, data = _run_python(zip_name) + exit_code, data = run_python(zip_name) expected = pattern % (run_name, "__main__.Test") if verbose: print "Expected line", expected @@ -211,16 +209,16 @@ pdb.runcall(f) """) with temp_dir() as d: - script_name = _make_test_script(d, 'script', test_src) - p = _spawn_python(script_name) + script_name = make_script(d, 'script', test_src) + p = spawn_python(script_name) p.stdin.write('l\n') - data = _kill_python(p) + data = kill_python(p) self.assertTrue(script_name in data) - zip_name, run_name = _make_test_zip(d, "test_zip", + zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') - p = _spawn_python(zip_name) + p = spawn_python(zip_name) p.stdin.write('l\n') - data = _kill_python(p) + data = kill_python(p) self.assertTrue(run_name in data) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 15 08:30:34 2009 @@ -429,6 +429,12 @@ Library ------- +- Issue #6816: runpy now provides a run_path function that allows Python code + to execute file paths that refer to source or compiled Python files as well + as zipfiles, directories and other valid sys.path entries that contain a + __main__.py file. This allows applications that run other Python scripts to + support the same flexibility as the CPython command line itself. + - Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for From python-checkins at python.org Sun Nov 15 08:35:20 2009 From: python-checkins at python.org (nick.coghlan) Date: Sun, 15 Nov 2009 07:35:20 -0000 Subject: [Python-checkins] r76287 - python/branches/release26-maint Message-ID: Author: nick.coghlan Date: Sun Nov 15 08:35:20 2009 New Revision: 76287 Log: Blocked revisions 76286 via svnmerge ........ r76286 | nick.coghlan | 2009-11-15 17:30:34 +1000 (Sun, 15 Nov 2009) | 1 line Issue #6816: expose the zipfile and directory execution mechanism to Python code via the runpy module. Also consolidated some script execution functionality in the test harness into a helper module and removed some implementation details from the runpy module documentation. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Nov 15 09:36:21 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 08:36:21 -0000 Subject: [Python-checkins] r76288 - python/trunk/Lib/urllib2.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 09:36:20 2009 New Revision: 76288 Log: Fix for Issue4683 - urllib2.HTTPDigestAuthHandler fails on third hostname?. Resolution: Reset the nonce value for each unique nonce (as per RFC 2617) Modified: python/trunk/Lib/urllib2.py Modified: python/trunk/Lib/urllib2.py ============================================================================== --- python/trunk/Lib/urllib2.py (original) +++ python/trunk/Lib/urllib2.py Sun Nov 15 09:36:20 2009 @@ -901,6 +901,7 @@ self.add_password = self.passwd.add_password self.retried = 0 self.nonce_count = 0 + self.last_nonce = None def reset_retry_count(self): self.retried = 0 @@ -975,7 +976,12 @@ # XXX selector: what about proxies and full urls req.get_selector()) if qop == 'auth': - self.nonce_count += 1 + if nonce == self.last_nonce: + self.nonce_count += 1 + else: + self.nonce_count = 1 + self.last_nonce = nonce + ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) From python-checkins at python.org Sun Nov 15 09:39:10 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 08:39:10 -0000 Subject: [Python-checkins] r76289 - in python/branches/release26-maint: Lib/urllib2.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 09:39:10 2009 New Revision: 76289 Log: Merged revisions 76288 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76288 | senthil.kumaran | 2009-11-15 14:06:20 +0530 (Sun, 15 Nov 2009) | 3 lines Fix for Issue4683 - urllib2.HTTPDigestAuthHandler fails on third hostname?. Resolution: Reset the nonce value for each unique nonce (as per RFC 2617) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/urllib2.py Modified: python/branches/release26-maint/Lib/urllib2.py ============================================================================== --- python/branches/release26-maint/Lib/urllib2.py (original) +++ python/branches/release26-maint/Lib/urllib2.py Sun Nov 15 09:39:10 2009 @@ -901,6 +901,7 @@ self.add_password = self.passwd.add_password self.retried = 0 self.nonce_count = 0 + self.last_nonce = None def reset_retry_count(self): self.retried = 0 @@ -975,7 +976,12 @@ # XXX selector: what about proxies and full urls req.get_selector()) if qop == 'auth': - self.nonce_count += 1 + if nonce == self.last_nonce: + self.nonce_count += 1 + else: + self.nonce_count = 1 + self.last_nonce = nonce + ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) From python-checkins at python.org Sun Nov 15 09:43:46 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 08:43:46 -0000 Subject: [Python-checkins] r76290 - in python/branches/py3k: Lib/urllib/request.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 09:43:45 2009 New Revision: 76290 Log: Merged revisions 76288 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76288 | senthil.kumaran | 2009-11-15 14:06:20 +0530 (Sun, 15 Nov 2009) | 3 lines Fix for Issue4683 - urllib2.HTTPDigestAuthHandler fails on third hostname?. Resolution: Reset the nonce value for each unique nonce (as per RFC 2617) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/urllib/request.py Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Sun Nov 15 09:43:45 2009 @@ -847,6 +847,7 @@ self.add_password = self.passwd.add_password self.retried = 0 self.nonce_count = 0 + self.last_nonce = None def reset_retry_count(self): self.retried = 0 @@ -922,7 +923,11 @@ # XXX selector: what about proxies and full urls req.selector) if qop == 'auth': - self.nonce_count += 1 + if nonce == self.last_nonce: + self.nonce_count += 1 + else: + self.nonce_count = 1 + self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) From python-checkins at python.org Sun Nov 15 09:45:28 2009 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 15 Nov 2009 08:45:28 -0000 Subject: [Python-checkins] r76291 - in python/branches/release31-maint: Lib/urllib/request.py Message-ID: Author: senthil.kumaran Date: Sun Nov 15 09:45:27 2009 New Revision: 76291 Log: Merged revisions 76290 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76290 | senthil.kumaran | 2009-11-15 14:13:45 +0530 (Sun, 15 Nov 2009) | 10 lines Merged revisions 76288 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76288 | senthil.kumaran | 2009-11-15 14:06:20 +0530 (Sun, 15 Nov 2009) | 3 lines Fix for Issue4683 - urllib2.HTTPDigestAuthHandler fails on third hostname?. Resolution: Reset the nonce value for each unique nonce (as per RFC 2617) ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/urllib/request.py Modified: python/branches/release31-maint/Lib/urllib/request.py ============================================================================== --- python/branches/release31-maint/Lib/urllib/request.py (original) +++ python/branches/release31-maint/Lib/urllib/request.py Sun Nov 15 09:45:27 2009 @@ -847,6 +847,7 @@ self.add_password = self.passwd.add_password self.retried = 0 self.nonce_count = 0 + self.last_nonce = None def reset_retry_count(self): self.retried = 0 @@ -922,7 +923,11 @@ # XXX selector: what about proxies and full urls req.selector) if qop == 'auth': - self.nonce_count += 1 + if nonce == self.last_nonce: + self.nonce_count += 1 + else: + self.nonce_count = 1 + self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count cnonce = self.get_cnonce(nonce) noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) From python-checkins at python.org Sun Nov 15 10:57:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 09:57:27 -0000 Subject: [Python-checkins] r76292 - in python/branches/py3k: Lib/test/test_range.py Misc/NEWS Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 10:57:26 2009 New Revision: 76292 Log: Issue #7298: Fix a variety of problems leading to wrong results with the fast versions of range.__reversed__ and range iteration. Also fix wrong results and a refleak for PyLong version of range.__reversed__. Thanks Eric Smith for reviewing, and for suggesting improved tests. Modified: python/branches/py3k/Lib/test/test_range.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/rangeobject.c Modified: python/branches/py3k/Lib/test/test_range.py ============================================================================== --- python/branches/py3k/Lib/test/test_range.py (original) +++ python/branches/py3k/Lib/test/test_range.py Sun Nov 15 10:57:26 2009 @@ -3,12 +3,49 @@ import test.support, unittest import sys import pickle +import itertools import warnings warnings.filterwarnings("ignore", "integer argument expected", DeprecationWarning, "unittest") +# pure Python implementations (3 args only), for comparison +def pyrange(start, stop, step): + if (start - stop) // step < 0: + # replace stop with next element in the sequence of integers + # that are congruent to start modulo step. + stop += (start - stop) % step + while start != stop: + yield start + start += step + +def pyrange_reversed(start, stop, step): + stop += (start - stop) % step + return pyrange(stop - step, start - step, -step) + + class RangeTest(unittest.TestCase): + def assert_iterators_equal(self, xs, ys, test_id, limit=None): + # check that an iterator xs matches the expected results ys, + # up to a given limit. + if limit is not None: + xs = itertools.islice(xs, limit) + ys = itertools.islice(ys, limit) + sentinel = object() + pairs = itertools.zip_longest(xs, ys, fillvalue=sentinel) + for i, (x, y) in enumerate(pairs): + if x == y: + continue + elif x == sentinel: + self.fail('{}: iterator ended unexpectedly ' + 'at position {}; expected {}'.format(test_id, i, y)) + elif y == sentinel: + self.fail('{}: unexpected excess element {} at ' + 'position {}'.format(test_id, x, i)) + else: + self.fail('{}: wrong element at position {};' + 'expected {}, got {}'.format(test_id, i, y, x)) + def test_range(self): self.assertEqual(list(range(3)), [0, 1, 2]) self.assertEqual(list(range(1, 5)), [1, 2, 3, 4]) @@ -134,6 +171,30 @@ self.assertFalse(-1 in r) self.assertFalse(1 in r) + def test_range_iterators(self): + # exercise 'fast' iterators, that use a rangeiterobject internally. + # see issue 7298 + limits = [base + jiggle + for M in (2**32, 2**64) + for base in (-M, -M//2, 0, M//2, M) + for jiggle in (-2, -1, 0, 1, 2)] + test_ranges = [(start, end, step) + for start in limits + for end in limits + for step in (-2**63, -2**31, -2, -1, 1, 2)] + + for start, end, step in test_ranges: + iter1 = range(start, end, step) + iter2 = pyrange(start, end, step) + test_id = "range({}, {}, {})".format(start, end, step) + # check first 100 entries + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + + iter1 = reversed(range(start, end, step)) + iter2 = pyrange_reversed(start, end, step) + test_id = "reversed(range({}, {}, {}))".format(start, end, step) + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + def test_main(): test.support.run_unittest(RangeTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 15 10:57:26 2009 @@ -12,6 +12,12 @@ Core and Builtins ----------------- +- Issue #7298: fixes for range and reversed(range(...)). Iteration + over range(a, b, c) incorrectly gave an empty iterator when a, b and + c fit in C long but the length of the range did not. Also fix + several cases where reversed(range(a, b, c)) gave wrong results, and + fix a refleak for reversed(range(a, b, c)) with large arguments. + - Issue #7244: itertools.izip_longest() no longer ignores exceptions raised during the formation of an output tuple. Modified: python/branches/py3k/Objects/rangeobject.c ============================================================================== --- python/branches/py3k/Objects/rangeobject.c (original) +++ python/branches/py3k/Objects/rangeobject.c Sun Nov 15 10:57:26 2009 @@ -488,16 +488,15 @@ rangeiter_new, /* tp_new */ }; -/* Return number of items in range (lo, hi, step). step > 0 - * required. Return a value < 0 if & only if the true value is too - * large to fit in a signed long. +/* Return number of items in range (lo, hi, step). step != 0 + * required. The result always fits in an unsigned long. */ -static long +static unsigned long get_len_of_range(long lo, long hi, long step) { /* ------------------------------------------------------------- - If lo >= hi, the range is empty. - Else if n values are in the range, the last one is + If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty. + Else for step > 0, if n values are in the range, the last one is lo + (n-1)*step, which must be <= hi-1. Rearranging, n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so @@ -505,30 +504,37 @@ floor. Letting M be the largest positive long, the worst case for the RHS numerator is hi=M, lo=-M-1, and then hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough - precision to compute the RHS exactly. + precision to compute the RHS exactly. The analysis for step < 0 + is similar. ---------------------------------------------------------------*/ - long n = 0; - if (lo < hi) { - unsigned long uhi = (unsigned long)hi; - unsigned long ulo = (unsigned long)lo; - unsigned long diff = uhi - ulo - 1; - n = (long)(diff / (unsigned long)step + 1); - } - return n; + assert(step != 0); + if (step > 0 && lo < hi) + return 1UL + (hi - 1UL - lo) / step; + else if (step < 0 && lo > hi) + return 1UL + (lo - 1UL - hi) / (0UL - step); + else + return 0UL; } +/* Initialize a rangeiter object. If the length of the rangeiter object + is not representable as a C long, OverflowError is raised. */ + static PyObject * int_range_iter(long start, long stop, long step) { rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + unsigned long ulen; if (it == NULL) return NULL; it->start = start; it->step = step; - if (step > 0) - it->len = get_len_of_range(start, stop, step); - else - it->len = get_len_of_range(stop, start, -step); + ulen = get_len_of_range(start, stop, step); + if (ulen > (unsigned long)LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "range too large to represent as a range_iterator"); + return NULL; + } + it->len = (long)ulen; it->index = 0; return (PyObject *)it; } @@ -637,23 +643,53 @@ rangeobject *r = (rangeobject *)seq; longrangeiterobject *it; long lstart, lstop, lstep; + PyObject *int_it; assert(PyRange_Check(seq)); - /* If all three fields convert to long, use the int version */ + /* If all three fields and the length convert to long, use the int + * version */ lstart = PyLong_AsLong(r->start); - if (lstart != -1 || !PyErr_Occurred()) { - lstop = PyLong_AsLong(r->stop); - if (lstop != -1 || !PyErr_Occurred()) { - lstep = PyLong_AsLong(r->step); - if (lstep != -1 || !PyErr_Occurred()) - return int_range_iter(lstart, lstop, lstep); - } - } - /* Some conversion failed, so there is an error set. Clear it, - and try again with a long range. */ - PyErr_Clear(); + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(r->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstep = PyLong_AsLong(r->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + /* round lstop to the next value congruent to lstart modulo lstep; + if the result would overflow, use PyLong version. */ + if (lstep > 0 && lstart < lstop) { + long extra = (lstep - 1) - (long)((lstop - 1UL - lstart) % lstep); + if ((unsigned long)extra > (unsigned long)LONG_MAX - lstop) + goto long_range; + lstop += extra; + } + else if (lstep < 0 && lstart > lstop) { + long extra = (lstep + 1) + (long)((lstart - 1UL - lstop) % + (0UL - lstep)); + if ((unsigned long)lstop - LONG_MIN < 0UL - extra) + goto long_range; + lstop += extra; + } + else + lstop = lstart; + + int_it = int_range_iter(lstart, lstop, lstep); + if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Clear(); + goto long_range; + } + return (PyObject *)int_it; + long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; @@ -686,34 +722,80 @@ rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; PyObject *one, *sum, *diff, *len = NULL, *product; - long lstart, lstop, lstep; + long lstart, lstop, lstep, new_start, new_stop; + unsigned long ulen; - /* XXX(nnorwitz): do the calc for the new start/stop first, - then if they fit, call the proper iter()? - */ assert(PyRange_Check(seq)); - /* If all three fields convert to long, use the int version */ + /* reversed(range(start, stop, step)) can be expressed as + range(start+(n-1)*step, start-step, -step), where n is the number of + integers in the range. + + If each of start, stop, step, -step, start-step, and the length + of the iterator is representable as a C long, use the int + version. This excludes some cases where the reversed range is + representable as a range_iterator, but it's good enough for + common cases and it makes the checks simple. */ + lstart = PyLong_AsLong(range->start); - if (lstart != -1 || !PyErr_Occurred()) { - lstop = PyLong_AsLong(range->stop); - if (lstop != -1 || !PyErr_Occurred()) { - lstep = PyLong_AsLong(range->step); - if (lstep != -1 || !PyErr_Occurred()) { - /* XXX(nnorwitz): need to check for overflow and simplify. */ - long len = get_len_of_range(lstart, lstop, lstep); - long new_start = lstart + (len - 1) * lstep; - long new_stop = lstart; - if (lstep > 0) - new_stop -= 1; - else - new_stop += 1; - return int_range_iter(new_start, new_stop, -lstep); - } - } + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(range->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; } - PyErr_Clear(); + lstep = PyLong_AsLong(range->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + /* check for possible overflow of -lstep */ + if (lstep == LONG_MIN) + goto long_range; + + /* check for overflow of lstart - lstep: + + for lstep > 0, need only check whether lstart - lstep < LONG_MIN. + for lstep < 0, need only check whether lstart - lstep > LONG_MAX + + Rearrange these inequalities as: + + lstart - LONG_MIN < lstep (lstep > 0) + LONG_MAX - lstart < -lstep (lstep < 0) + + and compute both sides as unsigned longs, to avoid the + possibility of undefined behaviour due to signed overflow. */ + + if (lstep > 0) { + if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep) + goto long_range; + } + else { + if (LONG_MAX - (unsigned long)lstart < 0UL - lstep) + goto long_range; + } + + /* set lstop equal to the last element of the range, or to lstart if the + range is empty. */ + if (lstep > 0 && lstart < lstop) + lstop += -1 - (long)((lstop - 1UL - lstart) % lstep); + else if (lstep < 0 && lstart > lstop) + lstop += 1 + (long)((lstart - 1UL - lstop) % (0UL - lstep)); + else + lstop = lstart; + + ulen = get_len_of_range(lstart, lstop, lstep); + if (ulen > (unsigned long)LONG_MAX) + goto long_range; + new_stop = lstart - lstep; + new_start = (long)(new_stop + ulen * lstep); + return int_range_iter(new_start, new_stop, -lstep); + +long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; @@ -732,7 +814,8 @@ if (!diff) goto create_failure; - product = PyNumber_Multiply(len, range->step); + product = PyNumber_Multiply(diff, range->step); + Py_DECREF(diff); if (!product) goto create_failure; @@ -741,11 +824,11 @@ it->start = sum; if (!it->start) goto create_failure; + it->step = PyNumber_Negative(range->step); if (!it->step) { Py_DECREF(it->start); - PyObject_Del(it); - return NULL; + goto create_failure; } /* Steal reference to len. */ From python-checkins at python.org Sun Nov 15 11:04:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 10:04:51 -0000 Subject: [Python-checkins] r76293 - python/branches/py3k/Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 11:04:50 2009 New Revision: 76293 Log: r76292 commit accidentally committed some extra code; remove it Modified: python/branches/py3k/Objects/rangeobject.c Modified: python/branches/py3k/Objects/rangeobject.c ============================================================================== --- python/branches/py3k/Objects/rangeobject.c (original) +++ python/branches/py3k/Objects/rangeobject.c Sun Nov 15 11:04:50 2009 @@ -664,24 +664,6 @@ PyErr_Clear(); goto long_range; } - /* round lstop to the next value congruent to lstart modulo lstep; - if the result would overflow, use PyLong version. */ - if (lstep > 0 && lstart < lstop) { - long extra = (lstep - 1) - (long)((lstop - 1UL - lstart) % lstep); - if ((unsigned long)extra > (unsigned long)LONG_MAX - lstop) - goto long_range; - lstop += extra; - } - else if (lstep < 0 && lstart > lstop) { - long extra = (lstep + 1) + (long)((lstart - 1UL - lstop) % - (0UL - lstep)); - if ((unsigned long)lstop - LONG_MIN < 0UL - extra) - goto long_range; - lstop += extra; - } - else - lstop = lstart; - int_it = int_range_iter(lstart, lstop, lstep); if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Clear(); @@ -778,15 +760,6 @@ goto long_range; } - /* set lstop equal to the last element of the range, or to lstart if the - range is empty. */ - if (lstep > 0 && lstart < lstop) - lstop += -1 - (long)((lstop - 1UL - lstart) % lstep); - else if (lstep < 0 && lstart > lstop) - lstop += 1 + (long)((lstart - 1UL - lstop) % (0UL - lstep)); - else - lstop = lstart; - ulen = get_len_of_range(lstart, lstop, lstep); if (ulen > (unsigned long)LONG_MAX) goto long_range; From python-checkins at python.org Sun Nov 15 11:17:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 10:17:48 -0000 Subject: [Python-checkins] r76294 - in python/branches/release31-maint: Lib/test/test_range.py Misc/NEWS Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 11:17:48 2009 New Revision: 76294 Log: Merged revisions 76292-76293 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76292 | mark.dickinson | 2009-11-15 09:57:26 +0000 (Sun, 15 Nov 2009) | 6 lines Issue #7298: Fix a variety of problems leading to wrong results with the fast versions of range.__reversed__ and range iteration. Also fix wrong results and a refleak for PyLong version of range.__reversed__. Thanks Eric Smith for reviewing, and for suggesting improved tests. ........ r76293 | mark.dickinson | 2009-11-15 10:04:50 +0000 (Sun, 15 Nov 2009) | 1 line r76292 commit accidentally committed some extra code; remove it ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_range.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Objects/rangeobject.c Modified: python/branches/release31-maint/Lib/test/test_range.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_range.py (original) +++ python/branches/release31-maint/Lib/test/test_range.py Sun Nov 15 11:17:48 2009 @@ -3,12 +3,49 @@ import test.support, unittest import sys import pickle +import itertools import warnings warnings.filterwarnings("ignore", "integer argument expected", DeprecationWarning, "unittest") +# pure Python implementations (3 args only), for comparison +def pyrange(start, stop, step): + if (start - stop) // step < 0: + # replace stop with next element in the sequence of integers + # that are congruent to start modulo step. + stop += (start - stop) % step + while start != stop: + yield start + start += step + +def pyrange_reversed(start, stop, step): + stop += (start - stop) % step + return pyrange(stop - step, start - step, -step) + + class RangeTest(unittest.TestCase): + def assert_iterators_equal(self, xs, ys, test_id, limit=None): + # check that an iterator xs matches the expected results ys, + # up to a given limit. + if limit is not None: + xs = itertools.islice(xs, limit) + ys = itertools.islice(ys, limit) + sentinel = object() + pairs = itertools.zip_longest(xs, ys, fillvalue=sentinel) + for i, (x, y) in enumerate(pairs): + if x == y: + continue + elif x == sentinel: + self.fail('{}: iterator ended unexpectedly ' + 'at position {}; expected {}'.format(test_id, i, y)) + elif y == sentinel: + self.fail('{}: unexpected excess element {} at ' + 'position {}'.format(test_id, x, i)) + else: + self.fail('{}: wrong element at position {};' + 'expected {}, got {}'.format(test_id, i, y, x)) + def test_range(self): self.assertEqual(list(range(3)), [0, 1, 2]) self.assertEqual(list(range(1, 5)), [1, 2, 3, 4]) @@ -78,6 +115,30 @@ with self.assertRaises(TypeError): range([], 1, -1) + def test_range_iterators(self): + # exercise 'fast' iterators, that use a rangeiterobject internally. + # see issue 7298 + limits = [base + jiggle + for M in (2**32, 2**64) + for base in (-M, -M//2, 0, M//2, M) + for jiggle in (-2, -1, 0, 1, 2)] + test_ranges = [(start, end, step) + for start in limits + for end in limits + for step in (-2**63, -2**31, -2, -1, 1, 2)] + + for start, end, step in test_ranges: + iter1 = range(start, end, step) + iter2 = pyrange(start, end, step) + test_id = "range({}, {}, {})".format(start, end, step) + # check first 100 entries + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + + iter1 = reversed(range(start, end, step)) + iter2 = pyrange_reversed(start, end, step) + test_id = "reversed(range({}, {}, {}))".format(start, end, step) + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + def test_main(): test.support.run_unittest(RangeTest) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sun Nov 15 11:17:48 2009 @@ -12,6 +12,12 @@ Core and Builtins ----------------- +- Issue #7298: fixes for range and reversed(range(...)). Iteration + over range(a, b, c) incorrectly gave an empty iterator when a, b and + c fit in C long but the length of the range did not. Also fix + several cases where reversed(range(a, b, c)) gave wrong results, and + fix a refleak for reversed(range(a, b, c)) with large arguments. + - Issue #7244: itertools.izip_longest() no longer ignores exceptions raised during the formation of an output tuple. Modified: python/branches/release31-maint/Objects/rangeobject.c ============================================================================== --- python/branches/release31-maint/Objects/rangeobject.c (original) +++ python/branches/release31-maint/Objects/rangeobject.c Sun Nov 15 11:17:48 2009 @@ -431,16 +431,15 @@ rangeiter_new, /* tp_new */ }; -/* Return number of items in range (lo, hi, step). step > 0 - * required. Return a value < 0 if & only if the true value is too - * large to fit in a signed long. +/* Return number of items in range (lo, hi, step). step != 0 + * required. The result always fits in an unsigned long. */ -static long +static unsigned long get_len_of_range(long lo, long hi, long step) { /* ------------------------------------------------------------- - If lo >= hi, the range is empty. - Else if n values are in the range, the last one is + If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty. + Else for step > 0, if n values are in the range, the last one is lo + (n-1)*step, which must be <= hi-1. Rearranging, n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so @@ -448,30 +447,37 @@ floor. Letting M be the largest positive long, the worst case for the RHS numerator is hi=M, lo=-M-1, and then hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough - precision to compute the RHS exactly. + precision to compute the RHS exactly. The analysis for step < 0 + is similar. ---------------------------------------------------------------*/ - long n = 0; - if (lo < hi) { - unsigned long uhi = (unsigned long)hi; - unsigned long ulo = (unsigned long)lo; - unsigned long diff = uhi - ulo - 1; - n = (long)(diff / (unsigned long)step + 1); - } - return n; + assert(step != 0); + if (step > 0 && lo < hi) + return 1UL + (hi - 1UL - lo) / step; + else if (step < 0 && lo > hi) + return 1UL + (lo - 1UL - hi) / (0UL - step); + else + return 0UL; } +/* Initialize a rangeiter object. If the length of the rangeiter object + is not representable as a C long, OverflowError is raised. */ + static PyObject * int_range_iter(long start, long stop, long step) { rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + unsigned long ulen; if (it == NULL) return NULL; it->start = start; it->step = step; - if (step > 0) - it->len = get_len_of_range(start, stop, step); - else - it->len = get_len_of_range(stop, start, -step); + ulen = get_len_of_range(start, stop, step); + if (ulen > (unsigned long)LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "range too large to represent as a range_iterator"); + return NULL; + } + it->len = (long)ulen; it->index = 0; return (PyObject *)it; } @@ -580,23 +586,35 @@ rangeobject *r = (rangeobject *)seq; longrangeiterobject *it; long lstart, lstop, lstep; + PyObject *int_it; assert(PyRange_Check(seq)); - /* If all three fields convert to long, use the int version */ + /* If all three fields and the length convert to long, use the int + * version */ lstart = PyLong_AsLong(r->start); - if (lstart != -1 || !PyErr_Occurred()) { - lstop = PyLong_AsLong(r->stop); - if (lstop != -1 || !PyErr_Occurred()) { - lstep = PyLong_AsLong(r->step); - if (lstep != -1 || !PyErr_Occurred()) - return int_range_iter(lstart, lstop, lstep); - } - } - /* Some conversion failed, so there is an error set. Clear it, - and try again with a long range. */ - PyErr_Clear(); + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(r->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstep = PyLong_AsLong(r->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + int_it = int_range_iter(lstart, lstop, lstep); + if (int_it == NULL && PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Clear(); + goto long_range; + } + return (PyObject *)int_it; + long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; @@ -629,34 +647,71 @@ rangeobject *range = (rangeobject*) seq; longrangeiterobject *it; PyObject *one, *sum, *diff, *len = NULL, *product; - long lstart, lstop, lstep; + long lstart, lstop, lstep, new_start, new_stop; + unsigned long ulen; - /* XXX(nnorwitz): do the calc for the new start/stop first, - then if they fit, call the proper iter()? - */ assert(PyRange_Check(seq)); - /* If all three fields convert to long, use the int version */ + /* reversed(range(start, stop, step)) can be expressed as + range(start+(n-1)*step, start-step, -step), where n is the number of + integers in the range. + + If each of start, stop, step, -step, start-step, and the length + of the iterator is representable as a C long, use the int + version. This excludes some cases where the reversed range is + representable as a range_iterator, but it's good enough for + common cases and it makes the checks simple. */ + lstart = PyLong_AsLong(range->start); - if (lstart != -1 || !PyErr_Occurred()) { - lstop = PyLong_AsLong(range->stop); - if (lstop != -1 || !PyErr_Occurred()) { - lstep = PyLong_AsLong(range->step); - if (lstep != -1 || !PyErr_Occurred()) { - /* XXX(nnorwitz): need to check for overflow and simplify. */ - long len = get_len_of_range(lstart, lstop, lstep); - long new_start = lstart + (len - 1) * lstep; - long new_stop = lstart; - if (lstep > 0) - new_stop -= 1; - else - new_stop += 1; - return int_range_iter(new_start, new_stop, -lstep); - } - } + if (lstart == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + lstop = PyLong_AsLong(range->stop); + if (lstop == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; } - PyErr_Clear(); + lstep = PyLong_AsLong(range->step); + if (lstep == -1 && PyErr_Occurred()) { + PyErr_Clear(); + goto long_range; + } + /* check for possible overflow of -lstep */ + if (lstep == LONG_MIN) + goto long_range; + + /* check for overflow of lstart - lstep: + + for lstep > 0, need only check whether lstart - lstep < LONG_MIN. + for lstep < 0, need only check whether lstart - lstep > LONG_MAX + + Rearrange these inequalities as: + lstart - LONG_MIN < lstep (lstep > 0) + LONG_MAX - lstart < -lstep (lstep < 0) + + and compute both sides as unsigned longs, to avoid the + possibility of undefined behaviour due to signed overflow. */ + + if (lstep > 0) { + if ((unsigned long)lstart - LONG_MIN < (unsigned long)lstep) + goto long_range; + } + else { + if (LONG_MAX - (unsigned long)lstart < 0UL - lstep) + goto long_range; + } + + ulen = get_len_of_range(lstart, lstop, lstep); + if (ulen > (unsigned long)LONG_MAX) + goto long_range; + + new_stop = lstart - lstep; + new_start = (long)(new_stop + ulen * lstep); + return int_range_iter(new_start, new_stop, -lstep); + +long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; @@ -675,7 +730,8 @@ if (!diff) goto create_failure; - product = PyNumber_Multiply(len, range->step); + product = PyNumber_Multiply(diff, range->step); + Py_DECREF(diff); if (!product) goto create_failure; @@ -684,11 +740,11 @@ it->start = sum; if (!it->start) goto create_failure; + it->step = PyNumber_Negative(range->step); if (!it->step) { Py_DECREF(it->start); - PyObject_Del(it); - return NULL; + goto create_failure; } /* Steal reference to len. */ From nnorwitz at gmail.com Sun Nov 15 13:12:20 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 15 Nov 2009 07:12:20 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091115121220.GA29560@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_runpy leaked [56, 56, 56] references, sum=168 Less important issues: ---------------------- test_popen2 leaked [-4, -25, 54] references, sum=25 test_ssl leaked [0, -420, 420] references, sum=0 From python-checkins at python.org Sun Nov 15 13:31:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 12:31:13 -0000 Subject: [Python-checkins] r76295 - in python/trunk: Lib/test/test_xrange.py Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 13:31:13 2009 New Revision: 76295 Log: Avoid signed overflow in some xrange calculations, and extend xrange tests to cover some special cases that caused problems in py3k. This is a partial backport of r76292-76293 (see issue #7298.) Modified: python/trunk/Lib/test/test_xrange.py python/trunk/Objects/rangeobject.c Modified: python/trunk/Lib/test/test_xrange.py ============================================================================== --- python/trunk/Lib/test/test_xrange.py (original) +++ python/trunk/Lib/test/test_xrange.py Sun Nov 15 13:31:13 2009 @@ -3,12 +3,49 @@ import test.test_support, unittest import sys import pickle +import itertools import warnings warnings.filterwarnings("ignore", "integer argument expected", DeprecationWarning, "unittest") +# pure Python implementations (3 args only), for comparison +def pyrange(start, stop, step): + if (start - stop) // step < 0: + # replace stop with next element in the sequence of integers + # that are congruent to start modulo step. + stop += (start - stop) % step + while start != stop: + yield start + start += step + +def pyrange_reversed(start, stop, step): + stop += (start - stop) % step + return pyrange(stop - step, start - step, -step) + + class XrangeTest(unittest.TestCase): + def assert_iterators_equal(self, xs, ys, test_id, limit=None): + # check that an iterator xs matches the expected results ys, + # up to a given limit. + if limit is not None: + xs = itertools.islice(xs, limit) + ys = itertools.islice(ys, limit) + sentinel = object() + pairs = itertools.izip_longest(xs, ys, fillvalue=sentinel) + for i, (x, y) in enumerate(pairs): + if x == y: + continue + elif x == sentinel: + self.fail('{}: iterator ended unexpectedly ' + 'at position {}; expected {}'.format(test_id, i, y)) + elif y == sentinel: + self.fail('{}: unexpected excess element {} at ' + 'position {}'.format(test_id, x, i)) + else: + self.fail('{}: wrong element at position {};' + 'expected {}, got {}'.format(test_id, i, y, x)) + def test_xrange(self): self.assertEqual(list(xrange(3)), [0, 1, 2]) self.assertEqual(list(xrange(1, 5)), [1, 2, 3, 4]) @@ -67,6 +104,37 @@ self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))), list(r)) + def test_range_iterators(self): + # see issue 7298 + limits = [base + jiggle + for M in (2**32, 2**64) + for base in (-M, -M//2, 0, M//2, M) + for jiggle in (-2, -1, 0, 1, 2)] + test_ranges = [(start, end, step) + for start in limits + for end in limits + for step in (-2**63, -2**31, -2, -1, 1, 2)] + + for start, end, step in test_ranges: + try: + iter1 = xrange(start, end, step) + except OverflowError: + pass + else: + iter2 = pyrange(start, end, step) + test_id = "xrange({}, {}, {})".format(start, end, step) + # check first 100 entries + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + + try: + iter1 = reversed(xrange(start, end, step)) + except OverflowError: + pass + else: + iter2 = pyrange_reversed(start, end, step) + test_id = "reversed(xrange({}, {}, {}))".format(start, end, step) + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + def test_main(): test.test_support.run_unittest(XrangeTest) Modified: python/trunk/Objects/rangeobject.c ============================================================================== --- python/trunk/Objects/rangeobject.c (original) +++ python/trunk/Objects/rangeobject.c Sun Nov 15 13:31:13 2009 @@ -9,33 +9,32 @@ long len; } rangeobject; -/* Return number of items in range/xrange (lo, hi, step). step > 0 - * required. Return a value < 0 if & only if the true value is too - * large to fit in a signed long. +/* Return number of items in range (lo, hi, step). step != 0 + * required. The result always fits in an unsigned long. */ -static long +static unsigned long get_len_of_range(long lo, long hi, long step) { - /* ------------------------------------------------------------- - If lo >= hi, the range is empty. - Else if n values are in the range, the last one is - lo + (n-1)*step, which must be <= hi-1. Rearranging, - n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives - the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so - the RHS is non-negative and so truncation is the same as the - floor. Letting M be the largest positive long, the worst case - for the RHS numerator is hi=M, lo=-M-1, and then - hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough - precision to compute the RHS exactly. - ---------------------------------------------------------------*/ - long n = 0; - if (lo < hi) { - unsigned long uhi = (unsigned long)hi; - unsigned long ulo = (unsigned long)lo; - unsigned long diff = uhi - ulo - 1; - n = (long)(diff / (unsigned long)step + 1); - } - return n; + /* ------------------------------------------------------------- + If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty. + Else for step > 0, if n values are in the range, the last one is + lo + (n-1)*step, which must be <= hi-1. Rearranging, + n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives + the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so + the RHS is non-negative and so truncation is the same as the + floor. Letting M be the largest positive long, the worst case + for the RHS numerator is hi=M, lo=-M-1, and then + hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough + precision to compute the RHS exactly. The analysis for step < 0 + is similar. + ---------------------------------------------------------------*/ + assert(step != 0); + if (step > 0 && lo < hi) + return 1UL + (hi - 1UL - lo) / step; + else if (step < 0 && lo > hi) + return 1UL + (lo - 1UL - hi) / (0UL - step); + else + return 0UL; } static PyObject * @@ -43,7 +42,7 @@ { rangeobject *obj; long ilow = 0, ihigh = 0, istep = 1; - long n; + unsigned long n; if (!_PyArg_NoKeywords("xrange()", kw)) return NULL; @@ -64,11 +63,8 @@ PyErr_SetString(PyExc_ValueError, "xrange() arg 3 must not be zero"); return NULL; } - if (istep > 0) - n = get_len_of_range(ilow, ihigh, istep); - else - n = get_len_of_range(ihigh, ilow, -istep); - if (n < 0) { + n = get_len_of_range(ilow, ihigh, istep); + if (n > (unsigned long)LONG_MAX || (long)n > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "xrange() result has too many items"); return NULL; @@ -78,7 +74,7 @@ if (obj == NULL) return NULL; obj->start = ilow; - obj->len = n; + obj->len = (long)n; obj->step = istep; return (PyObject *) obj; } @@ -98,7 +94,9 @@ "xrange object index out of range"); return NULL; } - return PyInt_FromSsize_t(r->start + i * r->step); + /* do calculation entirely using unsigned longs, to avoid + undefined behaviour due to signed overflow. */ + return PyInt_FromLong((long)(r->start + (unsigned long)i * r->step)); } static Py_ssize_t @@ -304,9 +302,21 @@ len = ((rangeobject *)seq)->len; it->index = 0; - it->start = start + (len-1) * step; - it->step = -step; it->len = len; + /* the casts below guard against signed overflow by turning it + into unsigned overflow instead. The correctness of this + code still depends on conversion from unsigned long to long + wrapping modulo ULONG_MAX+1, which isn't guaranteed (see + C99 6.3.1.3p3) but seems to hold in practice for all + platforms we're likely to meet. + + If step == LONG_MIN then we still end up with LONG_MIN + after negation; but this works out, since we've still got + the correct value modulo ULONG_MAX+1, and the range_item + calculation is also done modulo ULONG_MAX+1. + */ + it->start = (long)(start + (unsigned long)(len-1) * step); + it->step = (long)(-(unsigned long)step); return (PyObject *)it; } From python-checkins at python.org Sun Nov 15 13:34:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 12:34:13 -0000 Subject: [Python-checkins] r76296 - in python/branches/release26-maint: Lib/test/test_xrange.py Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 13:34:12 2009 New Revision: 76296 Log: Merged revisions 76295 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76295 | mark.dickinson | 2009-11-15 12:31:13 +0000 (Sun, 15 Nov 2009) | 5 lines Avoid signed overflow in some xrange calculations, and extend xrange tests to cover some special cases that caused problems in py3k. This is a partial backport of r76292-76293 (see issue #7298.) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_xrange.py python/branches/release26-maint/Objects/rangeobject.c Modified: python/branches/release26-maint/Lib/test/test_xrange.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_xrange.py (original) +++ python/branches/release26-maint/Lib/test/test_xrange.py Sun Nov 15 13:34:12 2009 @@ -3,12 +3,49 @@ import test.test_support, unittest import sys import pickle +import itertools import warnings warnings.filterwarnings("ignore", "integer argument expected", DeprecationWarning, "unittest") +# pure Python implementations (3 args only), for comparison +def pyrange(start, stop, step): + if (start - stop) // step < 0: + # replace stop with next element in the sequence of integers + # that are congruent to start modulo step. + stop += (start - stop) % step + while start != stop: + yield start + start += step + +def pyrange_reversed(start, stop, step): + stop += (start - stop) % step + return pyrange(stop - step, start - step, -step) + + class XrangeTest(unittest.TestCase): + def assert_iterators_equal(self, xs, ys, test_id, limit=None): + # check that an iterator xs matches the expected results ys, + # up to a given limit. + if limit is not None: + xs = itertools.islice(xs, limit) + ys = itertools.islice(ys, limit) + sentinel = object() + pairs = itertools.izip_longest(xs, ys, fillvalue=sentinel) + for i, (x, y) in enumerate(pairs): + if x == y: + continue + elif x == sentinel: + self.fail('{0}: iterator ended unexpectedly ' + 'at position {1}; expected {2}'.format(test_id, i, y)) + elif y == sentinel: + self.fail('{0}: unexpected excess element {1} at ' + 'position {2}'.format(test_id, x, i)) + else: + self.fail('{0}: wrong element at position {1};' + 'expected {2}, got {3}'.format(test_id, i, y, x)) + def test_xrange(self): self.assertEqual(list(xrange(3)), [0, 1, 2]) self.assertEqual(list(xrange(1, 5)), [1, 2, 3, 4]) @@ -67,6 +104,38 @@ self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))), list(r)) + def test_range_iterators(self): + # see issue 7298 + limits = [base + jiggle + for M in (2**32, 2**64) + for base in (-M, -M//2, 0, M//2, M) + for jiggle in (-2, -1, 0, 1, 2)] + test_ranges = [(start, end, step) + for start in limits + for end in limits + for step in (-2**63, -2**31, -2, -1, 1, 2)] + + for start, end, step in test_ranges: + try: + iter1 = xrange(start, end, step) + except OverflowError: + pass + else: + iter2 = pyrange(start, end, step) + test_id = "xrange({0}, {1}, {2})".format(start, end, step) + # check first 100 entries + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + + try: + iter1 = reversed(xrange(start, end, step)) + except OverflowError: + pass + else: + iter2 = pyrange_reversed(start, end, step) + test_id = "reversed(xrange({0}, {1}, {2}))".format( + start, end, step) + self.assert_iterators_equal(iter1, iter2, test_id, limit=100) + def test_main(): test.test_support.run_unittest(XrangeTest) Modified: python/branches/release26-maint/Objects/rangeobject.c ============================================================================== --- python/branches/release26-maint/Objects/rangeobject.c (original) +++ python/branches/release26-maint/Objects/rangeobject.c Sun Nov 15 13:34:12 2009 @@ -9,33 +9,32 @@ long len; } rangeobject; -/* Return number of items in range/xrange (lo, hi, step). step > 0 - * required. Return a value < 0 if & only if the true value is too - * large to fit in a signed long. +/* Return number of items in range (lo, hi, step). step != 0 + * required. The result always fits in an unsigned long. */ -static long +static unsigned long get_len_of_range(long lo, long hi, long step) { - /* ------------------------------------------------------------- - If lo >= hi, the range is empty. - Else if n values are in the range, the last one is - lo + (n-1)*step, which must be <= hi-1. Rearranging, - n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives - the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so - the RHS is non-negative and so truncation is the same as the - floor. Letting M be the largest positive long, the worst case - for the RHS numerator is hi=M, lo=-M-1, and then - hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough - precision to compute the RHS exactly. - ---------------------------------------------------------------*/ - long n = 0; - if (lo < hi) { - unsigned long uhi = (unsigned long)hi; - unsigned long ulo = (unsigned long)lo; - unsigned long diff = uhi - ulo - 1; - n = (long)(diff / (unsigned long)step + 1); - } - return n; + /* ------------------------------------------------------------- + If step > 0 and lo >= hi, or step < 0 and lo <= hi, the range is empty. + Else for step > 0, if n values are in the range, the last one is + lo + (n-1)*step, which must be <= hi-1. Rearranging, + n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives + the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so + the RHS is non-negative and so truncation is the same as the + floor. Letting M be the largest positive long, the worst case + for the RHS numerator is hi=M, lo=-M-1, and then + hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough + precision to compute the RHS exactly. The analysis for step < 0 + is similar. + ---------------------------------------------------------------*/ + assert(step != 0); + if (step > 0 && lo < hi) + return 1UL + (hi - 1UL - lo) / step; + else if (step < 0 && lo > hi) + return 1UL + (lo - 1UL - hi) / (0UL - step); + else + return 0UL; } static PyObject * @@ -43,7 +42,7 @@ { rangeobject *obj; long ilow = 0, ihigh = 0, istep = 1; - long n; + unsigned long n; if (!_PyArg_NoKeywords("xrange()", kw)) return NULL; @@ -64,11 +63,8 @@ PyErr_SetString(PyExc_ValueError, "xrange() arg 3 must not be zero"); return NULL; } - if (istep > 0) - n = get_len_of_range(ilow, ihigh, istep); - else - n = get_len_of_range(ihigh, ilow, -istep); - if (n < 0) { + n = get_len_of_range(ilow, ihigh, istep); + if (n > (unsigned long)LONG_MAX || (long)n > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "xrange() result has too many items"); return NULL; @@ -78,7 +74,7 @@ if (obj == NULL) return NULL; obj->start = ilow; - obj->len = n; + obj->len = (long)n; obj->step = istep; return (PyObject *) obj; } @@ -98,7 +94,9 @@ "xrange object index out of range"); return NULL; } - return PyInt_FromSsize_t(r->start + i * r->step); + /* do calculation entirely using unsigned longs, to avoid + undefined behaviour due to signed overflow. */ + return PyInt_FromLong((long)(r->start + (unsigned long)i * r->step)); } static Py_ssize_t @@ -304,9 +302,21 @@ len = ((rangeobject *)seq)->len; it->index = 0; - it->start = start + (len-1) * step; - it->step = -step; it->len = len; + /* the casts below guard against signed overflow by turning it + into unsigned overflow instead. The correctness of this + code still depends on conversion from unsigned long to long + wrapping modulo ULONG_MAX+1, which isn't guaranteed (see + C99 6.3.1.3p3) but seems to hold in practice for all + platforms we're likely to meet. + + If step == LONG_MIN then we still end up with LONG_MIN + after negation; but this works out, since we've still got + the correct value modulo ULONG_MAX+1, and the range_item + calculation is also done modulo ULONG_MAX+1. + */ + it->start = (long)(start + (unsigned long)(len-1) * step); + it->step = (long)(-(unsigned long)step); return (PyObject *)it; } From python-checkins at python.org Sun Nov 15 13:34:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 12:34:45 -0000 Subject: [Python-checkins] r76297 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Sun Nov 15 13:34:44 2009 New Revision: 76297 Log: Blocked revisions 76295 via svnmerge ........ r76295 | mark.dickinson | 2009-11-15 12:31:13 +0000 (Sun, 15 Nov 2009) | 5 lines Avoid signed overflow in some xrange calculations, and extend xrange tests to cover some special cases that caused problems in py3k. This is a partial backport of r76292-76293 (see issue #7298.) ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Nov 15 13:56:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 12:56:08 -0000 Subject: [Python-checkins] r76298 - python/branches/py3k/Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 13:56:08 2009 New Revision: 76298 Log: Fix another case of potential signed overflow. Modified: python/branches/py3k/Objects/rangeobject.c Modified: python/branches/py3k/Objects/rangeobject.c ============================================================================== --- python/branches/py3k/Objects/rangeobject.c (original) +++ python/branches/py3k/Objects/rangeobject.c Sun Nov 15 13:56:08 2009 @@ -411,7 +411,10 @@ rangeiter_next(rangeiterobject *r) { if (r->index < r->len) - return PyLong_FromLong(r->start + (r->index++) * r->step); + /* cast to unsigned to avoid possible signed overflow + in intermediate calculations. */ + return PyLong_FromLong((long)(r->start + + (unsigned long)(r->index++) * r->step)); return NULL; } From python-checkins at python.org Sun Nov 15 13:56:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 12:56:59 -0000 Subject: [Python-checkins] r76299 - in python/branches/release31-maint: Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 13:56:59 2009 New Revision: 76299 Log: Merged revisions 76298 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76298 | mark.dickinson | 2009-11-15 12:56:08 +0000 (Sun, 15 Nov 2009) | 1 line Fix another case of potential signed overflow. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Objects/rangeobject.c Modified: python/branches/release31-maint/Objects/rangeobject.c ============================================================================== --- python/branches/release31-maint/Objects/rangeobject.c (original) +++ python/branches/release31-maint/Objects/rangeobject.c Sun Nov 15 13:56:59 2009 @@ -354,7 +354,10 @@ rangeiter_next(rangeiterobject *r) { if (r->index < r->len) - return PyLong_FromLong(r->start + (r->index++) * r->step); + /* cast to unsigned to avoid possible signed overflow + in intermediate calculations. */ + return PyLong_FromLong((long)(r->start + + (unsigned long)(r->index++) * r->step)); return NULL; } From python-checkins at python.org Sun Nov 15 14:12:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 13:12:44 -0000 Subject: [Python-checkins] r76300 - in python/trunk: configure configure.in Message-ID: Author: mark.dickinson Date: Sun Nov 15 14:12:43 2009 New Revision: 76300 Log: Issue #5792: Extend short float repr support to x86 platforms using suncc or icc. Modified: python/trunk/configure python/trunk/configure.in Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sun Nov 15 14:12:43 2009 @@ -23626,15 +23626,15 @@ # correctly-rounded string <-> double conversion functions from # Python/dtoa.c, which in turn require that the FPU uses 53-bit # rounding; this is a problem on x86, where the x87 FPU has a default -# rounding precision of 64 bits. For gcc/x86, we try to fix this by +# rounding precision of 64 bits. For gcc/x86, we can fix this by # using inline assembler to get and set the x87 FPU control word. -if test "$GCC" = yes && test -n "`$CC -dM -E - &5 + +# This inline assembler syntax may also work for suncc and icc, +# so we try it on all platforms. + +{ echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } - cat >conftest.$ac_ext <<_ACEOF +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -23645,9 +23645,9 @@ main () { - unsigned short cw; - __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); - __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); ; return 0; @@ -23679,16 +23679,15 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 +{ echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 echo "${ECHO_T}$have_gcc_asm_for_x87" >&6; } - if test "$have_gcc_asm_for_x87" = yes - then +if test "$have_gcc_asm_for_x87" = yes +then cat >>confdefs.h <<\_ACEOF #define HAVE_GCC_ASM_FOR_X87 1 _ACEOF - fi fi # Detect whether system arithmetic is subject to x87-style double Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sun Nov 15 14:12:43 2009 @@ -3320,25 +3320,24 @@ # correctly-rounded string <-> double conversion functions from # Python/dtoa.c, which in turn require that the FPU uses 53-bit # rounding; this is a problem on x86, where the x87 FPU has a default -# rounding precision of 64 bits. For gcc/x86, we try to fix this by +# rounding precision of 64 bits. For gcc/x86, we can fix this by # using inline assembler to get and set the x87 FPU control word. -if test "$GCC" = yes && test -n "`$CC -dM -E - Author: mark.dickinson Revision: 76300 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1,2 @@ Issue #5792: Extend short float repr support to x86 platforms using suncc or icc. +Many thanks Stefan Krah for help and OpenSolaris testing. From python-checkins at python.org Sun Nov 15 14:47:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 13:47:27 -0000 Subject: [Python-checkins] r76301 - in python/branches/py3k: Misc/NEWS configure configure.in Message-ID: Author: mark.dickinson Date: Sun Nov 15 14:47:27 2009 New Revision: 76301 Log: Merged revisions 76300 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76300 | mark.dickinson | 2009-11-15 13:12:43 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #5792: Extend short float repr support to x86 platforms using suncc or icc. Many thanks Stefan Krah for help and OpenSolaris testing. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 15 14:47:27 2009 @@ -358,6 +358,9 @@ Build ----- +- Issue #5792: Extend the short float repr support to x86 systems using + icc or suncc. + - Issue #6603: Change READ_TIMESTAMP macro in ceval.c so that it compiles correctly under gcc on x86-64. This fixes a reported problem with the --with-tsc build on x86-64. Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Nov 15 14:47:27 2009 @@ -22945,15 +22945,15 @@ # correctly-rounded string <-> double conversion functions from # Python/dtoa.c, which in turn require that the FPU uses 53-bit # rounding; this is a problem on x86, where the x87 FPU has a default -# rounding precision of 64 bits. For gcc/x86, we try to fix this by +# rounding precision of 64 bits. For gcc/x86, we can fix this by # using inline assembler to get and set the x87 FPU control word. -if test "$GCC" = yes && test -n "`$CC -dM -E - &5 + +# This inline assembler syntax may also work for suncc and icc, +# so we try it on all platforms. + +{ echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } - cat >conftest.$ac_ext <<_ACEOF +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -22964,9 +22964,9 @@ main () { - unsigned short cw; - __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); - __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); ; return 0; @@ -22998,16 +22998,15 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 +{ echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 echo "${ECHO_T}$have_gcc_asm_for_x87" >&6; } - if test "$have_gcc_asm_for_x87" = yes - then +if test "$have_gcc_asm_for_x87" = yes +then cat >>confdefs.h <<\_ACEOF #define HAVE_GCC_ASM_FOR_X87 1 _ACEOF - fi fi # Detect whether system arithmetic is subject to x87-style double Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Nov 15 14:47:27 2009 @@ -3191,25 +3191,24 @@ # correctly-rounded string <-> double conversion functions from # Python/dtoa.c, which in turn require that the FPU uses 53-bit # rounding; this is a problem on x86, where the x87 FPU has a default -# rounding precision of 64 bits. For gcc/x86, we try to fix this by +# rounding precision of 64 bits. For gcc/x86, we can fix this by # using inline assembler to get and set the x87 FPU control word. -if test "$GCC" = yes && test -n "`$CC -dM -E - Author: mark.dickinson Date: Sun Nov 15 14:48:02 2009 New Revision: 76302 Log: Blocked revisions 76300 via svnmerge ........ r76300 | mark.dickinson | 2009-11-15 13:12:43 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #5792: Extend short float repr support to x86 platforms using suncc or icc. Many thanks Stefan Krah for help and OpenSolaris testing. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Nov 15 14:48:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 13:48:25 -0000 Subject: [Python-checkins] r76303 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Nov 15 14:48:24 2009 New Revision: 76303 Log: Blocked revisions 76301 via svnmerge ................ r76301 | mark.dickinson | 2009-11-15 13:47:27 +0000 (Sun, 15 Nov 2009) | 10 lines Merged revisions 76300 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76300 | mark.dickinson | 2009-11-15 13:12:43 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #5792: Extend short float repr support to x86 platforms using suncc or icc. Many thanks Stefan Krah for help and OpenSolaris testing. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Nov 15 14:58:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 13:58:50 -0000 Subject: [Python-checkins] r76304 - in python/branches/py3k: Lib/test/test_binop.py Misc/NEWS Objects/object.c Objects/typeobject.c Message-ID: Author: mark.dickinson Date: Sun Nov 15 14:58:49 2009 New Revision: 76304 Log: Issue #6970: Remove redundant calls made when comparing objects. Modified: python/branches/py3k/Lib/test/test_binop.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/object.c python/branches/py3k/Objects/typeobject.c Modified: python/branches/py3k/Lib/test/test_binop.py ============================================================================== --- python/branches/py3k/Lib/test/test_binop.py (original) +++ python/branches/py3k/Lib/test/test_binop.py Sun Nov 15 14:58:49 2009 @@ -2,6 +2,7 @@ import unittest from test import support +from operator import eq, ne, lt, gt, le, ge def gcd(a, b): """Greatest common divisor using Euclid's algorithm.""" @@ -305,9 +306,78 @@ # XXX Ran out of steam; TO DO: divmod, div, future division -def test_main(): - support.run_unittest(RatTestCase) +class OperationLogger: + """Base class for classes with operation logging.""" + def __init__(self, logger): + self.logger = logger + def log_operation(self, *args): + self.logger(*args) + +def op_sequence(op, *classes): + """Return the sequence of operations that results from applying + the operation `op` to instances of the given classes.""" + log = [] + instances = [] + for c in classes: + instances.append(c(log.append)) + + try: + op(*instances) + except TypeError: + pass + return log + +class A(OperationLogger): + def __eq__(self, other): + self.log_operation('A.__eq__') + return NotImplemented + def __le__(self, other): + self.log_operation('A.__le__') + return NotImplemented + def __ge__(self, other): + self.log_operation('A.__ge__') + return NotImplemented + +class B(OperationLogger): + def __eq__(self, other): + self.log_operation('B.__eq__') + return NotImplemented + def __le__(self, other): + self.log_operation('B.__le__') + return NotImplemented + def __ge__(self, other): + self.log_operation('B.__ge__') + return NotImplemented + +class C(B): + def __eq__(self, other): + self.log_operation('C.__eq__') + return NotImplemented + def __le__(self, other): + self.log_operation('C.__le__') + return NotImplemented + def __ge__(self, other): + self.log_operation('C.__ge__') + return NotImplemented + +class OperationOrderTests(unittest.TestCase): + def test_comparison_orders(self): + self.assertEqual(op_sequence(eq, A, A), ['A.__eq__', 'A.__eq__']) + self.assertEqual(op_sequence(eq, A, B), ['A.__eq__', 'B.__eq__']) + self.assertEqual(op_sequence(eq, B, A), ['B.__eq__', 'A.__eq__']) + # C is a subclass of B, so C.__eq__ is called first + self.assertEqual(op_sequence(eq, B, C), ['C.__eq__', 'B.__eq__']) + self.assertEqual(op_sequence(eq, C, B), ['C.__eq__', 'B.__eq__']) + + self.assertEqual(op_sequence(le, A, A), ['A.__le__', 'A.__ge__']) + self.assertEqual(op_sequence(le, A, B), ['A.__le__', 'B.__ge__']) + self.assertEqual(op_sequence(le, B, A), ['B.__le__', 'A.__ge__']) + self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__']) + self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__']) + +def test_main(): + support.run_unittest(RatTestCase, OperationOrderTests) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 15 14:58:49 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #6970: Remove redundant calls when comparing objects that don't + implement the relevant rich comparison methods. + - Issue #7298: fixes for range and reversed(range(...)). Iteration over range(a, b, c) incorrectly gave an empty iterator when a, b and c fit in C long but the length of the range did not. Also fix Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Sun Nov 15 14:58:49 2009 @@ -544,10 +544,12 @@ { richcmpfunc f; PyObject *res; + int checked_reverse_op = 0; if (v->ob_type != w->ob_type && PyType_IsSubtype(w->ob_type, v->ob_type) && (f = w->ob_type->tp_richcompare) != NULL) { + checked_reverse_op = 1; res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; @@ -559,7 +561,7 @@ return res; Py_DECREF(res); } - if ((f = w->ob_type->tp_richcompare) != NULL) { + if (!checked_reverse_op && (f = w->ob_type->tp_richcompare) != NULL) { res = (*f)(w, v, _Py_SwappedOp[op]); if (res != Py_NotImplemented) return res; Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sun Nov 15 14:58:49 2009 @@ -5068,7 +5068,7 @@ }; static PyObject * -half_richcompare(PyObject *self, PyObject *other, int op) +slot_tp_richcompare(PyObject *self, PyObject *other, int op) { PyObject *func, *args, *res; static PyObject *op_str[6]; @@ -5091,28 +5091,6 @@ } static PyObject * -slot_tp_richcompare(PyObject *self, PyObject *other, int op) -{ - PyObject *res; - - if (Py_TYPE(self)->tp_richcompare == slot_tp_richcompare) { - res = half_richcompare(self, other, op); - if (res != Py_NotImplemented) - return res; - Py_DECREF(res); - } - if (Py_TYPE(other)->tp_richcompare == slot_tp_richcompare) { - res = half_richcompare(other, self, _Py_SwappedOp[op]); - if (res != Py_NotImplemented) { - return res; - } - Py_DECREF(res); - } - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; -} - -static PyObject * slot_tp_iter(PyObject *self) { PyObject *func, *res; From python-checkins at python.org Sun Nov 15 14:59:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 13:59:19 -0000 Subject: [Python-checkins] r76305 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sun Nov 15 14:59:18 2009 New Revision: 76305 Log: Blocked revisions 76304 via svnmerge ........ r76304 | mark.dickinson | 2009-11-15 13:58:49 +0000 (Sun, 15 Nov 2009) | 2 lines Issue #6970: Remove redundant calls made when comparing objects. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Nov 15 15:10:49 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 15 Nov 2009 14:10:49 -0000 Subject: [Python-checkins] r76306 - in python/trunk: Doc/library/mimetypes.rst Lib/mimetypes.py Lib/test/test_mimetypes.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sun Nov 15 15:10:48 2009 New Revision: 76306 Log: Issue #4969: The mimetypes module now reads the MIME database from the registry under Windows. Patch by Gabriel Genellina. Modified: python/trunk/Doc/library/mimetypes.rst python/trunk/Lib/mimetypes.py python/trunk/Lib/test/test_mimetypes.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/mimetypes.rst ============================================================================== --- python/trunk/Doc/library/mimetypes.rst (original) +++ python/trunk/Doc/library/mimetypes.rst Sun Nov 15 15:10:48 2009 @@ -77,9 +77,13 @@ Initialize the internal data structures. If given, *files* must be a sequence of file names which should be used to augment the default type map. If omitted, - the file names to use are taken from :const:`knownfiles`. Each file named in - *files* or :const:`knownfiles` takes precedence over those named before it. - Calling :func:`init` repeatedly is allowed. + the file names to use are taken from :const:`knownfiles`; on Windows, the + current registry settings are loaded. Each file named in *files* or + :const:`knownfiles` takes precedence over those named before it. Calling + :func:`init` repeatedly is allowed. + + .. versionchanged:: 2.7 + Previously, Windows registry settings were ignored. .. function:: read_mime_types(filename) @@ -213,6 +217,12 @@ of the object. +.. method:: MimeTypes.guess_all_extensions(type[, strict]) + + Similar to the :func:`guess_all_extensions` function, using the tables stored as part + of the object. + + .. method:: MimeTypes.guess_type(url[, strict]) Similar to the :func:`guess_type` function, using the tables stored as part of @@ -230,3 +240,9 @@ Load MIME type information from an open file. The file must have the format of the standard :file:`mime.types` files. + +.. method:: MimeTypes.read_windows_registry() + + Load MIME type information from the Windows registry. Availability: Windows. + + .. versionadded:: 2.7 Modified: python/trunk/Lib/mimetypes.py ============================================================================== --- python/trunk/Lib/mimetypes.py (original) +++ python/trunk/Lib/mimetypes.py Sun Nov 15 15:10:48 2009 @@ -18,13 +18,19 @@ Functions: -init([files]) -- parse a list of files, default knownfiles +init([files]) -- parse a list of files, default knownfiles (on Windows, the + default values are taken from the registry) read_mime_types(file) -- parse one file, return a dictionary or None """ import os +import sys import posixpath import urllib +try: + import _winreg +except ImportError: + _winreg = None __all__ = [ "guess_type","guess_extension","guess_all_extensions", @@ -220,6 +226,52 @@ for suff in suffixes: self.add_type(type, '.' + suff, strict) + def read_windows_registry(self, strict=True): + """ + Load the MIME types database from Windows registry. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + + # Windows only + if not _winreg: + return + + def enum_types(mimedb): + i = 0 + while True: + try: + ctype = _winreg.EnumKey(mimedb, i) + except EnvironmentError: + break + try: + ctype = ctype.encode(default_encoding) # omit in 3.x! + except UnicodeEncodeError: + pass + else: + yield ctype + i += 1 + + default_encoding = sys.getdefaultencoding() + with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, + r'MIME\Database\Content Type') as mimedb: + for ctype in enum_types(mimedb): + with _winreg.OpenKey(mimedb, ctype) as key: + try: + suffix, datatype = _winreg.QueryValueEx(key, 'Extension') + except EnvironmentError: + continue + if datatype != _winreg.REG_SZ: + continue + try: + suffix = suffix.encode(default_encoding) # omit in 3.x! + except UnicodeEncodeError: + continue + self.add_type(ctype, suffix, strict) + + def guess_type(url, strict=True): """Guess the type of a file based on its URL. @@ -299,6 +351,8 @@ inited = True # so that MimeTypes.__init__() doesn't call us again db = MimeTypes() if files is None: + if _winreg: + db.read_windows_registry() files = knownfiles for file in files: if os.path.isfile(file): Modified: python/trunk/Lib/test/test_mimetypes.py ============================================================================== --- python/trunk/Lib/test/test_mimetypes.py (original) +++ python/trunk/Lib/test/test_mimetypes.py Sun Nov 15 15:10:48 2009 @@ -1,6 +1,7 @@ import mimetypes import StringIO import unittest +import sys from test import test_support @@ -62,8 +63,31 @@ eq(all, []) + at unittest.skipUnless(sys.platform.startswith("win"), "Windows only") +class Win32MimeTypesTestCase(unittest.TestCase): + def setUp(self): + # ensure all entries actually come from the Windows registry + self.original_types_map = mimetypes.types_map.copy() + mimetypes.types_map.clear() + mimetypes.init() + self.db = mimetypes.MimeTypes() + + def tearDown(self): + # restore default settings + mimetypes.types_map.clear() + mimetypes.types_map.update(self.original_types_map) + + def test_registry_parsing(self): + # the original, minimum contents of the MIME database in the + # Windows registry is undocumented AFAIK. + # Use file types that should *always* exist: + eq = self.assertEqual + eq(self.db.guess_type("foo.txt"), ("text/plain", None)) + def test_main(): - test_support.run_unittest(MimeTypesTestCase) + test_support.run_unittest(MimeTypesTestCase, + Win32MimeTypesTestCase + ) if __name__ == "__main__": Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 15 15:10:48 2009 @@ -429,6 +429,9 @@ Library ------- +- Issue #4969: The mimetypes module now reads the MIME database from + the registry under Windows. Patch by Gabriel Genellina. + - Issue #6816: runpy now provides a run_path function that allows Python code to execute file paths that refer to source or compiled Python files as well as zipfiles, directories and other valid sys.path entries that contain a From python-checkins at python.org Sun Nov 15 15:25:16 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 15 Nov 2009 14:25:16 -0000 Subject: [Python-checkins] r76307 - in python/branches/py3k: Doc/library/mimetypes.rst Lib/mimetypes.py Lib/test/test_mimetypes.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sun Nov 15 15:25:16 2009 New Revision: 76307 Log: Merged revisions 76306 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76306 | antoine.pitrou | 2009-11-15 15:10:48 +0100 (dim., 15 nov. 2009) | 4 lines Issue #4969: The mimetypes module now reads the MIME database from the registry under Windows. Patch by Gabriel Genellina. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/mimetypes.rst python/branches/py3k/Lib/mimetypes.py python/branches/py3k/Lib/test/test_mimetypes.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/mimetypes.rst ============================================================================== --- python/branches/py3k/Doc/library/mimetypes.rst (original) +++ python/branches/py3k/Doc/library/mimetypes.rst Sun Nov 15 15:25:16 2009 @@ -76,9 +76,13 @@ Initialize the internal data structures. If given, *files* must be a sequence of file names which should be used to augment the default type map. If omitted, - the file names to use are taken from :const:`knownfiles`. Each file named in - *files* or :const:`knownfiles` takes precedence over those named before it. - Calling :func:`init` repeatedly is allowed. + the file names to use are taken from :const:`knownfiles`; on Windows, the + current registry settings are loaded. Each file named in *files* or + :const:`knownfiles` takes precedence over those named before it. Calling + :func:`init` repeatedly is allowed. + + .. versionchanged:: 3.2 + Previously, Windows registry settings were ignored. .. function:: read_mime_types(filename) @@ -228,3 +232,9 @@ Load MIME type information from an open file. The file must have the format of the standard :file:`mime.types` files. + +.. method:: MimeTypes.read_windows_registry() + + Load MIME type information from the Windows registry. Availability: Windows. + + .. versionadded:: 3.2 Modified: python/branches/py3k/Lib/mimetypes.py ============================================================================== --- python/branches/py3k/Lib/mimetypes.py (original) +++ python/branches/py3k/Lib/mimetypes.py Sun Nov 15 15:25:16 2009 @@ -18,13 +18,19 @@ Functions: -init([files]) -- parse a list of files, default knownfiles +init([files]) -- parse a list of files, default knownfiles (on Windows, the + default values are taken from the registry) read_mime_types(file) -- parse one file, return a dictionary or None """ import os +import sys import posixpath import urllib.parse +try: + import winreg as _winreg +except ImportError: + _winreg = None __all__ = [ "guess_type","guess_extension","guess_all_extensions", @@ -220,6 +226,44 @@ for suff in suffixes: self.add_type(type, '.' + suff, strict) + def read_windows_registry(self, strict=True): + """ + Load the MIME types database from Windows registry. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + + # Windows only + if not _winreg: + return + + def enum_types(mimedb): + i = 0 + while True: + try: + ctype = _winreg.EnumKey(mimedb, i) + except EnvironmentError: + break + else: + yield ctype + i += 1 + + default_encoding = sys.getdefaultencoding() + with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, + r'MIME\Database\Content Type') as mimedb: + for ctype in enum_types(mimedb): + with _winreg.OpenKey(mimedb, ctype) as key: + try: + suffix, datatype = _winreg.QueryValueEx(key, 'Extension') + except EnvironmentError: + continue + if datatype != _winreg.REG_SZ: + continue + self.add_type(ctype, suffix, strict) + + def guess_type(url, strict=True): """Guess the type of a file based on its URL. @@ -299,6 +343,8 @@ inited = True # so that MimeTypes.__init__() doesn't call us again db = MimeTypes() if files is None: + if _winreg: + db.read_windows_registry() files = knownfiles for file in files: if os.path.isfile(file): Modified: python/branches/py3k/Lib/test/test_mimetypes.py ============================================================================== --- python/branches/py3k/Lib/test/test_mimetypes.py (original) +++ python/branches/py3k/Lib/test/test_mimetypes.py Sun Nov 15 15:25:16 2009 @@ -1,6 +1,7 @@ import mimetypes import io import unittest +import sys from test import support @@ -62,8 +63,32 @@ eq(all, []) + at unittest.skipUnless(sys.platform.startswith("win"), "Windows only") +class Win32MimeTypesTestCase(unittest.TestCase): + def setUp(self): + # ensure all entries actually come from the Windows registry + self.original_types_map = mimetypes.types_map.copy() + mimetypes.types_map.clear() + mimetypes.init() + self.db = mimetypes.MimeTypes() + + def tearDown(self): + # restore default settings + mimetypes.types_map.clear() + mimetypes.types_map.update(self.original_types_map) + + def test_registry_parsing(self): + # the original, minimum contents of the MIME database in the + # Windows registry is undocumented AFAIK. + # Use file types that should *always* exist: + eq = self.assertEqual + eq(self.db.guess_type("foo.txt"), ("text/plain", None)) + + def test_main(): - support.run_unittest(MimeTypesTestCase) + support.run_unittest(MimeTypesTestCase, + Win32MimeTypesTestCase + ) if __name__ == "__main__": Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 15 15:25:16 2009 @@ -132,6 +132,9 @@ Library ------- +- Issue #4969: The mimetypes module now reads the MIME database from + the registry under Windows. Patch by Gabriel Genellina. + - Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for From python-checkins at python.org Sun Nov 15 17:18:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 16:18:59 -0000 Subject: [Python-checkins] r76308 - in python/trunk: Doc/c-api/exceptions.rst Doc/c-api/string.rst Include/pyport.h Misc/NEWS Modules/_testcapimodule.c Objects/stringobject.c configure configure.in pyconfig.h.in Message-ID: Author: mark.dickinson Date: Sun Nov 15 17:18:58 2009 New Revision: 76308 Log: Issue #7228: Add '%lld' and '%llu' support to PyFormat_FromString, PyFormat_FromStringV and PyErr_Format. Modified: python/trunk/Doc/c-api/exceptions.rst python/trunk/Doc/c-api/string.rst python/trunk/Include/pyport.h python/trunk/Misc/NEWS python/trunk/Modules/_testcapimodule.c python/trunk/Objects/stringobject.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in Modified: python/trunk/Doc/c-api/exceptions.rst ============================================================================== --- python/trunk/Doc/c-api/exceptions.rst (original) +++ python/trunk/Doc/c-api/exceptions.rst Sun Nov 15 17:18:58 2009 @@ -161,6 +161,8 @@ .. % The descriptions for %zd and %zu are wrong, but the truth is complicated .. % because not all compilers support the %z width modifier -- we fake it .. % when necessary via interpolating PY_FORMAT_SIZE_T. + .. % Similar comments apply to the %ll width modifier and + .. % PY_FORMAT_LONG_LONG. .. % %u, %lu, %zu should have "new in Python 2.5" blurbs. +-------------------+---------------+--------------------------------+ @@ -183,6 +185,12 @@ | :attr:`%lu` | unsigned long | Exactly equivalent to | | | | ``printf("%lu")``. | +-------------------+---------------+--------------------------------+ + | :attr:`%lld` | long long | Exactly equivalent to | + | | | ``printf("%lld")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%llu` | unsigned | Exactly equivalent to | + | | long long | ``printf("%llu")``. | + +-------------------+---------------+--------------------------------+ | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | | | | ``printf("%zd")``. | +-------------------+---------------+--------------------------------+ @@ -210,6 +218,14 @@ An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. + .. note:: + + The `"%lld"` and `"%llu"` format specifiers are only available + when `HAVE_LONG_LONG` is defined. + + .. versionchanged:: 2.7 + Support for `"%lld"` and `"%llu"` added. + .. cfunction:: void PyErr_SetNone(PyObject *type) Modified: python/trunk/Doc/c-api/string.rst ============================================================================== --- python/trunk/Doc/c-api/string.rst (original) +++ python/trunk/Doc/c-api/string.rst Sun Nov 15 17:18:58 2009 @@ -78,6 +78,8 @@ .. % The descriptions for %zd and %zu are wrong, but the truth is complicated .. % because not all compilers support the %z width modifier -- we fake it .. % when necessary via interpolating PY_FORMAT_SIZE_T. + .. % Similar comments apply to the %ll width modifier and + .. % PY_FORMAT_LONG_LONG. .. % %u, %lu, %zu should have "new in Python 2.5" blurbs. +-------------------+---------------+--------------------------------+ @@ -100,6 +102,12 @@ | :attr:`%lu` | unsigned long | Exactly equivalent to | | | | ``printf("%lu")``. | +-------------------+---------------+--------------------------------+ + | :attr:`%lld` | long long | Exactly equivalent to | + | | | ``printf("%lld")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%llu` | unsigned | Exactly equivalent to | + | | long long | ``printf("%llu")``. | + +-------------------+---------------+--------------------------------+ | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | | | | ``printf("%zd")``. | +-------------------+---------------+--------------------------------+ @@ -127,6 +135,14 @@ An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. + .. note:: + + The `"%lld"` and `"%llu"` format specifiers are only available + when `HAVE_LONG_LONG` is defined. + + .. versionchanged:: 2.7 + Support for `"%lld"` and `"%llu"` added. + .. cfunction:: PyObject* PyString_FromFormatV(const char *format, va_list vargs) Modified: python/trunk/Include/pyport.h ============================================================================== --- python/trunk/Include/pyport.h (original) +++ python/trunk/Include/pyport.h Sun Nov 15 17:18:58 2009 @@ -229,6 +229,22 @@ # endif #endif +/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for + * the long long type instead of the size_t type. It's only available + * when HAVE_LONG_LONG is defined. The "high level" Python format + * functions listed above will interpret "lld" or "llu" correctly on + * all platforms. + */ +#ifdef HAVE_LONG_LONG +# ifndef PY_FORMAT_LONG_LONG +# if defined(MS_WIN64) || defined(MS_WINDOWS) +# define PY_FORMAT_LONG_LONG "I64" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG" +# endif +# endif +#endif + /* Py_LOCAL can be used instead of static to get the fastest possible calling * convention for functions that are local to a given module. * Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 15 17:18:58 2009 @@ -1462,6 +1462,9 @@ C-API ----- +- Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V) + and PyErr_Format, on machines with HAVE_LONG_LONG defined. + - Add new C-API function PyOS_string_to_double, and deprecated PyOS_ascii_atof and PyOS_ascii_strtod. Modified: python/trunk/Modules/_testcapimodule.c ============================================================================== --- python/trunk/Modules/_testcapimodule.c (original) +++ python/trunk/Modules/_testcapimodule.c Sun Nov 15 17:18:58 2009 @@ -954,6 +954,12 @@ CHECK_1_FORMAT("%lu", unsigned long); CHECK_1_FORMAT("%zu", size_t); + /* "%lld" and "%llu" support added in Python 2.7. */ +#ifdef HAVE_LONG_LONG + CHECK_1_FORMAT("%llu", unsigned PY_LONG_LONG); + CHECK_1_FORMAT("%lld", PY_LONG_LONG); +#endif + Py_RETURN_NONE; Fail: Modified: python/trunk/Objects/stringobject.c ============================================================================== --- python/trunk/Objects/stringobject.c (original) +++ python/trunk/Objects/stringobject.c Sun Nov 15 17:18:58 2009 @@ -189,6 +189,9 @@ /* step 1: figure out how large a buffer we need */ for (f = format; *f; f++) { if (*f == '%') { +#ifdef HAVE_LONG_LONG + int longlongflag = 0; +#endif const char* p = f; while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f))) ; @@ -196,9 +199,21 @@ /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since * they don't affect the amount of space we reserve. */ - if ((*f == 'l' || *f == 'z') && - (f[1] == 'd' || f[1] == 'u')) + if (*f == 'l') { + if (f[1] == 'd' || f[1] == 'u') { + ++f; + } +#ifdef HAVE_LONG_LONG + else if (f[1] == 'l' && + (f[2] == 'd' || f[2] == 'u')) { + longlongflag = 1; + f += 2; + } +#endif + } + else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { ++f; + } switch (*f) { case 'c': @@ -209,10 +224,21 @@ break; case 'd': case 'u': case 'i': case 'x': (void) va_arg(count, int); - /* 20 bytes is enough to hold a 64-bit - integer. Decimal takes the most space. - This isn't enough for octal. */ - n += 20; +#ifdef HAVE_LONG_LONG + /* Need at most + ceil(log10(256)*SIZEOF_LONG_LONG) digits, + plus 1 for the sign. 53/22 is an upper + bound for log10(256). */ + if (longlongflag) + n += 2 + (SIZEOF_LONG_LONG*53-1) / 22; + else +#endif + /* 20 bytes is enough to hold a 64-bit + integer. Decimal takes the most + space. This isn't enough for + octal. */ + n += 20; + break; case 's': s = va_arg(count, char*); @@ -255,6 +281,9 @@ const char* p = f++; Py_ssize_t i; int longflag = 0; +#ifdef HAVE_LONG_LONG + int longlongflag = 0; +#endif int size_tflag = 0; /* parse the width.precision part (we're only interested in the precision value, if any) */ @@ -269,14 +298,22 @@ } while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f))) f++; - /* handle the long flag, but only for %ld and %lu. - others can be added when necessary. */ - if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) { - longflag = 1; - ++f; + /* Handle %ld, %lu, %lld and %llu. */ + if (*f == 'l') { + if (f[1] == 'd' || f[1] == 'u') { + longflag = 1; + ++f; + } +#ifdef HAVE_LONG_LONG + else if (f[1] == 'l' && + (f[2] == 'd' || f[2] == 'u')) { + longlongflag = 1; + f += 2; + } +#endif } /* handle the size_t flag. */ - if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { + else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { size_tflag = 1; ++f; } @@ -288,6 +325,11 @@ case 'd': if (longflag) sprintf(s, "%ld", va_arg(vargs, long)); +#ifdef HAVE_LONG_LONG + else if (longlongflag) + sprintf(s, "%" PY_FORMAT_LONG_LONG "d", + va_arg(vargs, PY_LONG_LONG)); +#endif else if (size_tflag) sprintf(s, "%" PY_FORMAT_SIZE_T "d", va_arg(vargs, Py_ssize_t)); @@ -299,6 +341,11 @@ if (longflag) sprintf(s, "%lu", va_arg(vargs, unsigned long)); +#ifdef HAVE_LONG_LONG + else if (longlongflag) + sprintf(s, "%" PY_FORMAT_LONG_LONG "u", + va_arg(vargs, PY_LONG_LONG)); +#endif else if (size_tflag) sprintf(s, "%" PY_FORMAT_SIZE_T "u", va_arg(vargs, size_t)); Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sun Nov 15 17:18:58 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76052 . +# From configure.in Revision: 76300 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -27014,6 +27014,104 @@ echo "${ECHO_T}no" >&6; } fi +if test "$have_long_long" = yes +then + { echo "$as_me:$LINENO: checking for %lld and %llu printf() format support" >&5 +echo $ECHO_N "checking for %lld and %llu printf() format support... $ECHO_C" >&6; } + if test "${ac_cv_have_long_long_format+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_have_long_long_format=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + #include + #include + + #ifdef HAVE_SYS_TYPES_H + #include + #endif + + int main() + { + char buffer[256]; + + if (sprintf(buffer, "%lld", (long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + if (sprintf(buffer, "%lld", (long long)-123) < 0) + return 1; + if (strcmp(buffer, "-123")) + return 1; + + if (sprintf(buffer, "%llu", (unsigned long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + return 0; + } + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_long_long_format=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_have_long_long_format=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + + { echo "$as_me:$LINENO: result: $ac_cv_have_long_long_format" >&5 +echo "${ECHO_T}$ac_cv_have_long_long_format" >&6; } +fi + +if test $ac_cv_have_long_long_format = yes +then + +cat >>confdefs.h <<\_ACEOF +#define PY_FORMAT_LONG_LONG "ll" +_ACEOF + +fi + + { echo "$as_me:$LINENO: checking for %zd printf() format support" >&5 echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6; } if test "${ac_cv_have_size_t_format+set}" = set; then Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sun Nov 15 17:18:58 2009 @@ -3952,6 +3952,54 @@ AC_MSG_RESULT(no) fi +if test "$have_long_long" = yes +then + AC_MSG_CHECKING(for %lld and %llu printf() format support) + AC_CACHE_VAL(ac_cv_have_long_long_format, + AC_TRY_RUN([[ + #include + #include + #include + + #ifdef HAVE_SYS_TYPES_H + #include + #endif + + int main() + { + char buffer[256]; + + if (sprintf(buffer, "%lld", (long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + if (sprintf(buffer, "%lld", (long long)-123) < 0) + return 1; + if (strcmp(buffer, "-123")) + return 1; + + if (sprintf(buffer, "%llu", (unsigned long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + return 0; + } + ]], ac_cv_have_long_long_format=yes, + ac_cv_have_long_long_format=no, + ac_cv_have_long_long_format=no) + ) + AC_MSG_RESULT($ac_cv_have_long_long_format) +fi + +if test $ac_cv_have_long_long_format = yes +then + AC_DEFINE(PY_FORMAT_LONG_LONG, "ll", + [Define to printf format modifier for long long type]) +fi + + AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl AC_TRY_RUN([ #include Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Sun Nov 15 17:18:58 2009 @@ -903,6 +903,9 @@ /* Define as the preferred size in bits of long digits */ #undef PYLONG_BITS_IN_DIGIT +/* Define to printf format modifier for long long type */ +#undef PY_FORMAT_LONG_LONG + /* Define to printf format modifier for Py_ssize_t */ #undef PY_FORMAT_SIZE_T From python-checkins at python.org Sun Nov 15 18:22:10 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 15 Nov 2009 17:22:10 -0000 Subject: [Python-checkins] r76309 - in python/trunk: Doc/library/ftplib.rst Lib/ftplib.py Lib/test/test_ftplib.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sun Nov 15 18:22:09 2009 New Revision: 76309 Log: Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using TLS or SSL. Patch by Giampaolo Rodola'. Modified: python/trunk/Doc/library/ftplib.rst python/trunk/Lib/ftplib.py python/trunk/Lib/test/test_ftplib.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/ftplib.rst ============================================================================== --- python/trunk/Doc/library/ftplib.rst (original) +++ python/trunk/Doc/library/ftplib.rst Sun Nov 15 18:22:09 2009 @@ -49,6 +49,41 @@ .. versionchanged:: 2.6 *timeout* was added. +.. class:: FTP_TLS([host[, user[, passwd[, acct[, keyfile[, certfile[, timeout]]]]]]]) + + A :class:`FTP` subclass which adds TLS support to FTP as described in + :rfc:`4217`. + Connect as usual to port 21 implicitly securing the FTP control connection + before authenticating. Securing the data connection requires user to + explicitly ask for it by calling :exc:`prot_p()` method. + *keyfile* and *certfile* are optional - they can contain a PEM formatted + private key and certificate chain file for the SSL connection. + + .. versionadded:: 2.7 Contributed by Giampaolo Rodola' + + + Here's a sample session using :class:`FTP_TLS` class: + + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonimously previously securing control channel + >>> ftps.prot_p() # switch to secure data connection + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + >>> + + .. attribute:: all_errors @@ -329,3 +364,26 @@ :meth:`close` or :meth:`quit` you cannot reopen the connection by issuing another :meth:`login` method). + +FTP_TLS Objects +--------------- + +:class:`FTP_TLS` class inherits from :class:`FTP`, defining these additional objects: + +.. attribute:: FTP_TLS.ssl_version + + The SSL version to use (defaults to *TLSv1*). + +.. method:: FTP_TLS.auth() + + Set up secure control connection by using TLS or SSL, depending on what specified in :meth:`ssl_version` attribute. + +.. method:: FTP_TLS.prot_p() + + Set up secure data connection. + +.. method:: FTP_TLS.prot_c() + + Set up clear text data connection. + + Modified: python/trunk/Lib/ftplib.py ============================================================================== --- python/trunk/Lib/ftplib.py (original) +++ python/trunk/Lib/ftplib.py Sun Nov 15 18:22:09 2009 @@ -33,6 +33,7 @@ # Modified by Jack to work on the mac. # Modified by Siebren to support docstrings and PASV. # Modified by Phil Schwartz to add storbinary and storlines callbacks. +# Modified by Giampaolo Rodola' to add TLS support. # import os @@ -575,6 +576,181 @@ self.file = self.sock = None +try: + import ssl +except ImportError: + pass +else: + class FTP_TLS(FTP): + '''A FTP subclass which adds TLS support to FTP as described + in RFC-4217. + + Connect as usual to port 21 implicitly securing the FTP control + connection before authenticating. + + Securing the data connection requires user to explicitly ask + for it by calling prot_p() method. + + Usage example: + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonimously previously securing control channel + '230 Guest login ok, access restrictions apply.' + >>> ftps.prot_p() # switch to secure data connection + '200 Protection level set to P' + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + '221 Goodbye.' + >>> + ''' + ssl_version = ssl.PROTOCOL_TLSv1 + + def __init__(self, host='', user='', passwd='', acct='', keyfile=None, + certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + self.keyfile = keyfile + self.certfile = certfile + self._prot_p = False + FTP.__init__(self, host, user, passwd, acct, timeout) + + def login(self, user='', passwd='', acct='', secure=True): + if secure and not isinstance(self.sock, ssl.SSLSocket): + self.auth() + return FTP.login(self, user, passwd, acct) + + def auth(self): + '''Set up secure control connection by using TLS/SSL.''' + if isinstance(self.sock, ssl.SSLSocket): + raise ValueError("Already using TLS") + if self.ssl_version == ssl.PROTOCOL_TLSv1: + resp = self.voidcmd('AUTH TLS') + else: + resp = self.voidcmd('AUTH SSL') + self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + self.file = self.sock.makefile(mode='rb') + return resp + + def prot_p(self): + '''Set up secure data connection.''' + # PROT defines whether or not the data channel is to be protected. + # Though RFC-2228 defines four possible protection levels, + # RFC-4217 only recommends two, Clear and Private. + # Clear (PROT C) means that no security is to be used on the + # data-channel, Private (PROT P) means that the data-channel + # should be protected by TLS. + # PBSZ command MUST still be issued, but must have a parameter of + # '0' to indicate that no buffering is taking place and the data + # connection should not be encapsulated. + self.voidcmd('PBSZ 0') + resp = self.voidcmd('PROT P') + self._prot_p = True + return resp + + def prot_c(self): + '''Set up clear text data connection.''' + resp = self.voidcmd('PROT C') + self._prot_p = False + return resp + + # --- Overridden FTP methods + + def ntransfercmd(self, cmd, rest=None): + conn, size = FTP.ntransfercmd(self, cmd, rest) + if self._prot_p: + conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + return conn, size + + def retrbinary(self, cmd, callback, blocksize=8192, rest=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + try: + while 1: + data = conn.recv(blocksize) + if not data: + break + callback(data) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def retrlines(self, cmd, callback = None): + if callback is None: callback = print_line + resp = self.sendcmd('TYPE A') + conn = self.transfercmd(cmd) + fp = conn.makefile('rb') + try: + while 1: + line = fp.readline() + if self.debugging > 2: print '*retr*', repr(line) + if not line: + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] == '\n': + line = line[:-1] + callback(line) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + fp.close() + conn.close() + return self.voidresp() + + def storbinary(self, cmd, fp, blocksize=8192, callback=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.read(blocksize) + if not buf: break + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def storlines(self, cmd, fp, callback=None): + self.voidcmd('TYPE A') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.readline() + if not buf: break + if buf[-2:] != CRLF: + if buf[-1] in CRLF: buf = buf[:-1] + buf = buf + CRLF + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + __all__.append('FTP_TLS') + all_errors = (Error, IOError, EOFError, ssl.SSLError) + + _150_re = None def parse150(resp): Modified: python/trunk/Lib/test/test_ftplib.py ============================================================================== --- python/trunk/Lib/test/test_ftplib.py (original) +++ python/trunk/Lib/test/test_ftplib.py Sun Nov 15 18:22:09 2009 @@ -1,6 +1,7 @@ """Test script for ftplib module.""" -# Modified by Giampaolo Rodola' to test FTP class and IPv6 environment +# Modified by Giampaolo Rodola' to test FTP class, IPv6 and TLS +# environment import ftplib import threading @@ -8,6 +9,12 @@ import asynchat import socket import StringIO +import errno +import os +try: + import ssl +except ImportError: + ssl = None from unittest import TestCase from test import test_support @@ -38,6 +45,8 @@ class DummyFTPHandler(asynchat.async_chat): + dtp_handler = DummyDTPHandler + def __init__(self, conn): asynchat.async_chat.__init__(self, conn) self.set_terminator("\r\n") @@ -81,7 +90,7 @@ ip = '%d.%d.%d.%d' %tuple(addr[:4]) port = (addr[4] * 256) + addr[5] s = socket.create_connection((ip, port), timeout=2) - self.dtp = DummyDTPHandler(s, baseclass=self) + self.dtp = self.dtp_handler(s, baseclass=self) self.push('200 active data connection established') def cmd_pasv(self, arg): @@ -93,13 +102,13 @@ ip = ip.replace('.', ','); p1 = port / 256; p2 = port % 256 self.push('227 entering passive mode (%s,%d,%d)' %(ip, p1, p2)) conn, addr = sock.accept() - self.dtp = DummyDTPHandler(conn, baseclass=self) + self.dtp = self.dtp_handler(conn, baseclass=self) def cmd_eprt(self, arg): af, ip, port = arg.split(arg[0])[1:-1] port = int(port) s = socket.create_connection((ip, port), timeout=2) - self.dtp = DummyDTPHandler(s, baseclass=self) + self.dtp = self.dtp_handler(s, baseclass=self) self.push('200 active data connection established') def cmd_epsv(self, arg): @@ -110,7 +119,7 @@ port = sock.getsockname()[1] self.push('229 entering extended passive mode (|||%d|)' %port) conn, addr = sock.accept() - self.dtp = DummyDTPHandler(conn, baseclass=self) + self.dtp = self.dtp_handler(conn, baseclass=self) def cmd_echo(self, arg): # sends back the received string (used by the test suite) @@ -225,6 +234,126 @@ raise +if ssl is not None: + + CERTFILE = os.path.join(os.path.dirname(__file__), "keycert.pem") + + class SSLConnection(object, asyncore.dispatcher): + """An asyncore.dispatcher subclass supporting TLS/SSL.""" + + _ssl_accepting = False + + def secure_connection(self): + self.socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False, + certfile=CERTFILE, server_side=True, + do_handshake_on_connect=False, + ssl_version=ssl.PROTOCOL_SSLv23) + self._ssl_accepting = True + + def _do_ssl_handshake(self): + try: + self.socket.do_handshake() + except ssl.SSLError, err: + if err.args[0] in (ssl.SSL_ERROR_WANT_READ, + ssl.SSL_ERROR_WANT_WRITE): + return + elif err.args[0] == ssl.SSL_ERROR_EOF: + return self.handle_close() + raise + except socket.error, err: + if err.args[0] == errno.ECONNABORTED: + return self.handle_close() + else: + self._ssl_accepting = False + + def handle_read_event(self): + if self._ssl_accepting: + self._do_ssl_handshake() + else: + super(SSLConnection, self).handle_read_event() + + def handle_write_event(self): + if self._ssl_accepting: + self._do_ssl_handshake() + else: + super(SSLConnection, self).handle_write_event() + + def send(self, data): + try: + return super(SSLConnection, self).send(data) + except ssl.SSLError, err: + if err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): + return 0 + raise + + def recv(self, buffer_size): + try: + return super(SSLConnection, self).recv(buffer_size) + except ssl.SSLError, err: + if err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): + self.handle_close() + return '' + raise + + def handle_error(self): + raise + + def close(self): + try: + if isinstance(self.socket, ssl.SSLSocket): + if self.socket._sslobj is not None: + self.socket.unwrap() + finally: + super(SSLConnection, self).close() + + + class DummyTLS_DTPHandler(SSLConnection, DummyDTPHandler): + """A DummyDTPHandler subclass supporting TLS/SSL.""" + + def __init__(self, conn, baseclass): + DummyDTPHandler.__init__(self, conn, baseclass) + if self.baseclass.secure_data_channel: + self.secure_connection() + + + class DummyTLS_FTPHandler(SSLConnection, DummyFTPHandler): + """A DummyFTPHandler subclass supporting TLS/SSL.""" + + dtp_handler = DummyTLS_DTPHandler + + def __init__(self, conn): + DummyFTPHandler.__init__(self, conn) + self.secure_data_channel = False + + def cmd_auth(self, line): + """Set up secure control channel.""" + self.push('234 AUTH TLS successful') + self.secure_connection() + + def cmd_pbsz(self, line): + """Negotiate size of buffer for secure data transfer. + For TLS/SSL the only valid value for the parameter is '0'. + Any other value is accepted but ignored. + """ + self.push('200 PBSZ=0 successful.') + + def cmd_prot(self, line): + """Setup un/secure data channel.""" + arg = line.upper() + if arg == 'C': + self.push('200 Protection set to Clear') + self.secure_data_channel = False + elif arg == 'P': + self.push('200 Protection set to Private') + self.secure_data_channel = True + else: + self.push("502 Unrecognized PROT type (use C or P).") + + + class DummyTLS_FTPServer(DummyFTPServer): + handler = DummyTLS_FTPHandler + + class TestFTPClass(TestCase): def setUp(self): @@ -398,6 +527,81 @@ retr() +class TestTLS_FTPClassMixin(TestFTPClass): + """Repeat TestFTPClass tests starting the TLS layer for both control + and data connections first. + """ + + def setUp(self): + self.server = DummyTLS_FTPServer((HOST, 0)) + self.server.start() + self.client = ftplib.FTP_TLS(timeout=2) + self.client.connect(self.server.host, self.server.port) + # enable TLS + self.client.auth() + self.client.prot_p() + + +class TestTLS_FTPClass(TestCase): + """Specific TLS_FTP class tests.""" + + def setUp(self): + self.server = DummyTLS_FTPServer((HOST, 0)) + self.server.start() + self.client = ftplib.FTP_TLS(timeout=2) + self.client.connect(self.server.host, self.server.port) + + def tearDown(self): + self.client.close() + self.server.stop() + + def test_control_connection(self): + self.assertFalse(isinstance(self.client.sock, ssl.SSLSocket)) + self.client.auth() + self.assertTrue(isinstance(self.client.sock, ssl.SSLSocket)) + + def test_data_connection(self): + # clear text + sock = self.client.transfercmd('list') + self.assertFalse(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + # secured, after PROT P + self.client.prot_p() + sock = self.client.transfercmd('list') + self.assertTrue(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + # PROT C is issued, the connection must be in cleartext again + self.client.prot_c() + sock = self.client.transfercmd('list') + self.assertFalse(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + def test_login(self): + # login() is supposed to implicitly secure the control connection + self.assertFalse(isinstance(self.client.sock, ssl.SSLSocket)) + self.client.login() + self.assertTrue(isinstance(self.client.sock, ssl.SSLSocket)) + # make sure that AUTH TLS doesn't get issued again + self.client.login() + + def test_auth_issued_twice(self): + self.client.auth() + self.assertRaises(ValueError, self.client.auth) + + def test_auth_ssl(self): + try: + self.client.ssl_version = ssl.PROTOCOL_SSLv3 + self.client.auth() + self.assertRaises(ValueError, self.client.auth) + finally: + self.client.ssl_version = ssl.PROTOCOL_TLSv1 + + class TestTimeouts(TestCase): def setUp(self): @@ -499,6 +703,10 @@ pass else: tests.append(TestIPv6Environment) + + if ssl is not None: + tests.extend([TestTLS_FTPClassMixin, TestTLS_FTPClass]) + thread_info = test_support.threading_setup() try: test_support.run_unittest(*tests) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 15 18:22:09 2009 @@ -429,6 +429,9 @@ Library ------- +- Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using + TLS or SSL. Patch by Giampaolo Rodola'. + - Issue #4969: The mimetypes module now reads the MIME database from the registry under Windows. Patch by Gabriel Genellina. From python-checkins at python.org Sun Nov 15 19:23:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 18:23:13 -0000 Subject: [Python-checkins] r76310 - python/branches/py3k/pyconfig.h.in Message-ID: Author: mark.dickinson Date: Sun Nov 15 19:23:13 2009 New Revision: 76310 Log: Regenerate pyconfig.h.in using autoconf 2.61 Modified: python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sun Nov 15 19:23:13 2009 @@ -5,9 +5,6 @@ #define Py_PYCONFIG_H -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want support for AIX C++ shared extension modules. */ #undef AIX_GENUINE_CPLUSPLUS @@ -491,9 +488,6 @@ /* Define if your compiler supports function prototype */ #undef HAVE_PROTOTYPES -/* Define if you have GNU PTH threads. */ -#undef HAVE_PTH - /* Defined for Solaris 2.6 bug in pthread header. */ #undef HAVE_PTHREAD_DESTRUCTOR @@ -1013,28 +1007,6 @@ /* Define if you want to use computed gotos in ceval.c. */ #undef USE_COMPUTED_GOTOS -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - /* Define if a va_list is an array of some kind */ #undef VA_LIST_IS_ARRAY @@ -1072,21 +1044,20 @@ /* Define to profile with the Pentium timestamp counter */ #undef WITH_TSC -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN /* Define if arithmetic is subject to x87-style double rounding issue */ #undef X87_DOUBLE_ROUNDING +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + /* Define on OpenBSD to activate all library features */ #undef _BSD_SOURCE @@ -1105,25 +1076,15 @@ /* This must be defined on some systems to enable large file support. */ #undef _LARGEFILE_SOURCE -/* Define to 1 if on MINIX. */ -#undef _MINIX - /* Define on NetBSD to activate all library features */ #undef _NETBSD_SOURCE /* Define _OSF_SOURCE to get the makedev macro. */ #undef _OSF_SOURCE -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - /* Define to activate features from IEEE Stds 1003.1-2001 */ #undef _POSIX_C_SOURCE -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - /* Define if you have POSIX threads, and your system does not define that. */ #undef _POSIX_THREADS @@ -1131,12 +1092,12 @@ #undef _REENTRANT /* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the + , or is not used. If the typedef was allowed, the #define below would cause a syntax error. */ #undef _UINT32_T /* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the + , or is not used. If the typedef was allowed, the #define below would cause a syntax error. */ #undef _UINT64_T From python-checkins at python.org Sun Nov 15 19:25:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 15 Nov 2009 18:25:24 -0000 Subject: [Python-checkins] r76311 - in python/branches/release31-maint: pyconfig.h.in Message-ID: Author: mark.dickinson Date: Sun Nov 15 19:25:23 2009 New Revision: 76311 Log: Merged revisions 76310 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76310 | mark.dickinson | 2009-11-15 18:23:13 +0000 (Sun, 15 Nov 2009) | 1 line Regenerate pyconfig.h.in using autoconf 2.61 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/pyconfig.h.in Modified: python/branches/release31-maint/pyconfig.h.in ============================================================================== --- python/branches/release31-maint/pyconfig.h.in (original) +++ python/branches/release31-maint/pyconfig.h.in Sun Nov 15 19:25:23 2009 @@ -5,9 +5,6 @@ #define Py_PYCONFIG_H -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want support for AIX C++ shared extension modules. */ #undef AIX_GENUINE_CPLUSPLUS @@ -1001,28 +998,6 @@ /* Define if you want to use computed gotos in ceval.c. */ #undef USE_COMPUTED_GOTOS -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - /* Define if a va_list is an array of some kind */ #undef VA_LIST_IS_ARRAY @@ -1060,21 +1035,20 @@ /* Define to profile with the Pentium timestamp counter */ #undef WITH_TSC -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN /* Define if arithmetic is subject to x87-style double rounding issue */ #undef X87_DOUBLE_ROUNDING +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + /* Define on OpenBSD to activate all library features */ #undef _BSD_SOURCE @@ -1093,25 +1067,15 @@ /* This must be defined on some systems to enable large file support. */ #undef _LARGEFILE_SOURCE -/* Define to 1 if on MINIX. */ -#undef _MINIX - /* Define on NetBSD to activate all library features */ #undef _NETBSD_SOURCE /* Define _OSF_SOURCE to get the makedev macro. */ #undef _OSF_SOURCE -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - /* Define to activate features from IEEE Stds 1003.1-2001 */ #undef _POSIX_C_SOURCE -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - /* Define if you have POSIX threads, and your system does not define that. */ #undef _POSIX_THREADS @@ -1119,12 +1083,12 @@ #undef _REENTRANT /* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the + , or is not used. If the typedef was allowed, the #define below would cause a syntax error. */ #undef _UINT32_T /* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the + , or is not used. If the typedef was allowed, the #define below would cause a syntax error. */ #undef _UINT64_T From brett at python.org Sun Nov 15 21:40:32 2009 From: brett at python.org (Brett Cannon) Date: Sun, 15 Nov 2009 12:40:32 -0800 Subject: [Python-checkins] Using itertools in modules that are part of the build chain (Re: r76264 - python/branches/py3k/Lib/tokenize.py) In-Reply-To: <1afaf6160911142001m39d0f0ceyd3646e922d3bf703@mail.gmail.com> References: <4afeda77.0702d00a.4fa1.488cSMTPIN_ADDED@mx.google.com> <4AFF7048.7070701@gmail.com> <1afaf6160911142001m39d0f0ceyd3646e922d3bf703@mail.gmail.com> Message-ID: On Sat, Nov 14, 2009 at 20:01, Benjamin Peterson wrote: > 2009/11/14 Nick Coghlan : >> This does constrain where we can use itertools - if we want carte >> blanche to use it anywhere in the standard library, even those parts >> that are imported as part of the build chain, we'll need to bite the >> bullet and make it a builtin module rather than a separately built >> extension module. > > I have another unpleasant but slightly less hacky solution. We put > detect_encoding in linecache where it is actually used. Well, it happens to be used by the standard library in linecache, but not all external uses of it necessarily tie into linecache (e.g. importlib uses detect_encoding() in some non-critical code). Might just have to live with sub-optimal code. -Brett From benjamin at python.org Sun Nov 15 21:43:10 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sun, 15 Nov 2009 14:43:10 -0600 Subject: [Python-checkins] Using itertools in modules that are part of the build chain (Re: r76264 - python/branches/py3k/Lib/tokenize.py) In-Reply-To: References: <4afeda77.0702d00a.4fa1.488cSMTPIN_ADDED@mx.google.com> <4AFF7048.7070701@gmail.com> <1afaf6160911142001m39d0f0ceyd3646e922d3bf703@mail.gmail.com> Message-ID: <1afaf6160911151243s23c56722lfa00010f14a0d6b3@mail.gmail.com> 2009/11/15 Brett Cannon : > On Sat, Nov 14, 2009 at 20:01, Benjamin Peterson wrote: >> 2009/11/14 Nick Coghlan : >>> This does constrain where we can use itertools - if we want carte >>> blanche to use it anywhere in the standard library, even those parts >>> that are imported as part of the build chain, we'll need to bite the >>> bullet and make it a builtin module rather than a separately built >>> extension module. >> >> I have another unpleasant but slightly less hacky solution. We put >> detect_encoding in linecache where it is actually used. > > Well, it happens to be used by the standard library in linecache, but > not all external uses of it necessarily tie into linecache (e.g. > importlib uses detect_encoding() in some non-critical code). Might > just have to live with sub-optimal code. Well, what I mean is that we'd do: def _detect_encoding(): in linecache and then "from linecache import _detect_encoding as detect_encoding" in tokenize.py. -- Regards, Benjamin From python-checkins at python.org Sun Nov 15 23:36:48 2009 From: python-checkins at python.org (nick.coghlan) Date: Sun, 15 Nov 2009 22:36:48 -0000 Subject: [Python-checkins] r76312 - in python/trunk: Lib/pydoc.py Misc/NEWS Message-ID: Author: nick.coghlan Date: Sun Nov 15 23:36:47 2009 New Revision: 76312 Log: Issue #7328: don't corrupt sys.path when running pydoc with the -m switch Modified: python/trunk/Lib/pydoc.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/pydoc.py ============================================================================== --- python/trunk/Lib/pydoc.py (original) +++ python/trunk/Lib/pydoc.py Sun Nov 15 23:36:47 2009 @@ -2254,11 +2254,13 @@ import getopt class BadUsage: pass - # Scripts don't get the current directory in their path by default. - scriptdir = os.path.dirname(sys.argv[0]) - if scriptdir in sys.path: - sys.path.remove(scriptdir) - sys.path.insert(0, '.') + # Scripts don't get the current directory in their path by default + # unless they are run with the '-m' switch + if '' not in sys.path: + scriptdir = os.path.dirname(sys.argv[0]) + if scriptdir in sys.path: + sys.path.remove(scriptdir) + sys.path.insert(0, '.') try: opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 15 23:36:47 2009 @@ -429,6 +429,8 @@ Library ------- +- Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch + - Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using TLS or SSL. Patch by Giampaolo Rodola'. From python-checkins at python.org Sun Nov 15 23:58:27 2009 From: python-checkins at python.org (nick.coghlan) Date: Sun, 15 Nov 2009 22:58:27 -0000 Subject: [Python-checkins] r76313 - in python/branches/release26-maint: Lib/pydoc.py Misc/NEWS Message-ID: Author: nick.coghlan Date: Sun Nov 15 23:58:27 2009 New Revision: 76313 Log: Merged revisions 76312 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76312 | nick.coghlan | 2009-11-16 08:36:47 +1000 (Mon, 16 Nov 2009) | 1 line Issue #7328: don't corrupt sys.path when running pydoc with the -m switch ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/pydoc.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/pydoc.py ============================================================================== --- python/branches/release26-maint/Lib/pydoc.py (original) +++ python/branches/release26-maint/Lib/pydoc.py Sun Nov 15 23:58:27 2009 @@ -2254,11 +2254,13 @@ import getopt class BadUsage: pass - # Scripts don't get the current directory in their path by default. - scriptdir = os.path.dirname(sys.argv[0]) - if scriptdir in sys.path: - sys.path.remove(scriptdir) - sys.path.insert(0, '.') + # Scripts don't get the current directory in their path by default + # unless they are run with the '-m' switch + if '' not in sys.path: + scriptdir = os.path.dirname(sys.argv[0]) + if scriptdir in sys.path: + sys.path.remove(scriptdir) + sys.path.insert(0, '.') try: opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Nov 15 23:58:27 2009 @@ -26,6 +26,8 @@ Library ------- +- Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch + - Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for From nnorwitz at gmail.com Mon Nov 16 00:01:13 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 15 Nov 2009 18:01:13 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (3) Message-ID: <20091115230113.GA27518@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [-80, 0, 0] references, sum=-80 test_runpy leaked [56, 56, 56] references, sum=168 test_warnings leaked [0, 120, 0] references, sum=120 Less important issues: ---------------------- test_cmd_line leaked [0, 0, -25] references, sum=-25 test_ssl leaked [-339, 339, 0] references, sum=0 From python-checkins at python.org Mon Nov 16 00:04:34 2009 From: python-checkins at python.org (nick.coghlan) Date: Sun, 15 Nov 2009 23:04:34 -0000 Subject: [Python-checkins] r76314 - in python/branches/py3k: Lib/pydoc.py Misc/NEWS Message-ID: Author: nick.coghlan Date: Mon Nov 16 00:04:33 2009 New Revision: 76314 Log: Merged revisions 76312 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76312 | nick.coghlan | 2009-11-16 08:36:47 +1000 (Mon, 16 Nov 2009) | 1 line Issue #7328: don't corrupt sys.path when running pydoc with the -m switch ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/pydoc.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Mon Nov 16 00:04:33 2009 @@ -2249,11 +2249,13 @@ import getopt class BadUsage(Exception): pass - # Scripts don't get the current directory in their path by default. - scriptdir = os.path.dirname(sys.argv[0]) - if scriptdir in sys.path: - sys.path.remove(scriptdir) - sys.path.insert(0, '.') + # Scripts don't get the current directory in their path by default + # unless they are run with the '-m' switch + if '' not in sys.path: + scriptdir = os.path.dirname(sys.argv[0]) + if scriptdir in sys.path: + sys.path.remove(scriptdir) + sys.path.insert(0, '.') try: opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 16 00:04:33 2009 @@ -132,6 +132,8 @@ Library ------- +- Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch + - Issue #4969: The mimetypes module now reads the MIME database from the registry under Windows. Patch by Gabriel Genellina. From python-checkins at python.org Mon Nov 16 00:27:31 2009 From: python-checkins at python.org (nick.coghlan) Date: Sun, 15 Nov 2009 23:27:31 -0000 Subject: [Python-checkins] r76315 - in python/branches/release31-maint: Lib/pydoc.py Misc/NEWS Message-ID: Author: nick.coghlan Date: Mon Nov 16 00:27:31 2009 New Revision: 76315 Log: Recorded merge of revisions 76314 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76314 | nick.coghlan | 2009-11-16 09:04:33 +1000 (Mon, 16 Nov 2009) | 9 lines Merged revisions 76312 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76312 | nick.coghlan | 2009-11-16 08:36:47 +1000 (Mon, 16 Nov 2009) | 1 line Issue #7328: don't corrupt sys.path when running pydoc with the -m switch ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/pydoc.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/pydoc.py ============================================================================== --- python/branches/release31-maint/Lib/pydoc.py (original) +++ python/branches/release31-maint/Lib/pydoc.py Mon Nov 16 00:27:31 2009 @@ -2249,11 +2249,13 @@ import getopt class BadUsage(Exception): pass - # Scripts don't get the current directory in their path by default. - scriptdir = os.path.dirname(sys.argv[0]) - if scriptdir in sys.path: - sys.path.remove(scriptdir) - sys.path.insert(0, '.') + # Scripts don't get the current directory in their path by default + # unless they are run with the '-m' switch + if '' not in sys.path: + scriptdir = os.path.dirname(sys.argv[0]) + if scriptdir in sys.path: + sys.path.remove(scriptdir) + sys.path.insert(0, '.') try: opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w') Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Nov 16 00:27:31 2009 @@ -46,6 +46,8 @@ Library ------- +- Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch + - Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for From solipsis at pitrou.net Mon Nov 16 00:44:53 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 16 Nov 2009 00:44:53 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76310): sum=462 Message-ID: <20091115234453.135AA17714@ns6635.ovh.net> py3k results for svn r76310 (hg cset 422c5fda4170) -------------------------------------------------- test_range leaked [150, 150, 150] references, sum=450 test_urllib leaked [4, 4, 4] references, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogjw04o8', '-x', 'test_httpservers'] From python-checkins at python.org Mon Nov 16 01:11:20 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 16 Nov 2009 00:11:20 -0000 Subject: [Python-checkins] r76316 - in python/branches/tarek_sysconfig/Lib: sysconfig.py test/test_sysconfig.py Message-ID: Author: tarek.ziade Date: Mon Nov 16 01:11:20 2009 New Revision: 76316 Log: added missing paths and removed unecessary APIs Modified: python/branches/tarek_sysconfig/Lib/sysconfig.py python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Modified: python/branches/tarek_sysconfig/Lib/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/sysconfig.py Mon Nov 16 01:11:20 2009 @@ -1,76 +1,83 @@ +"""Provide access to Python's configuration information. + +""" import sys import os from os.path import pardir, abspath _INSTALL_SCHEMES = { 'unix_prefix': { + 'stdlib': '$base/lib/python$py_version_short', + 'platstdlib': '$platbase/lib/python$py_version_short', 'purelib': '$base/lib/python$py_version_short/site-packages', 'platlib': '$platbase/lib/python$py_version_short/site-packages', - 'headers': '$base/include/python$py_version_short/$dist_name', + 'include': '$base/include/python$py_version_short', + 'platinclude': '$platbase/include/python$py_version_short', 'scripts': '$base/bin', - 'data' : '$base', + 'data': '$base', }, 'unix_home': { + 'stdlib': '$base/lib/python', + 'platstdlib': '$base/lib/python', 'purelib': '$base/lib/python', 'platlib': '$base/lib/python', - 'headers': '$base/include/python/$dist_name', + 'include': '$base/include/python', + 'platinclude': '$base/include/python', 'scripts': '$base/bin', 'data' : '$base', }, 'nt': { + 'stdlib': '$base/Lib', + 'platstdlib': '$base/Lib', 'purelib': '$base/Lib/site-packages', 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - }, - 'mac': { - 'purelib': '$base/Lib/site-packages', - 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', + 'include': '$base/include', + 'platinclude': '$base/include', 'scripts': '$base/Scripts', 'data' : '$base', }, - 'os2': { + 'stdlib': '$base/Lib', + 'platstdlib': '$base/Lib', 'purelib': '$base/Lib/site-packages', 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', + 'include': '$base/Include', + 'platinclude': '$base/Include', 'scripts': '$base/Scripts', 'data' : '$base', }, + 'os2_home': { + 'stdlib': '$userbase/lib/python/$py_version_short', + 'platstdlib': '$userbase/lib/python/$py_version_short', + 'purelib': '$userbase/lib/python/$py_version_short/site-packages', + 'platlib': '$userbase/lib/python/$py_version_short/site-packages', + 'include': '$userbase/include/python$py_version_short', + 'scripts': '$userbase/bin', + 'data' : '$userbase', + }, 'nt_user': { + 'stdlib': '$userbase/Python/$py_version_nodot', + 'platstdlib': '$userbase/Python/$py_version_nodot', 'purelib': '$userbase/Python/$py_version_nodot/site-packages', 'platlib': '$userbase/Python/$py_version_nodot/site-packages', - 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', + 'include': '$userbase/Python$py_version_nodot/Include', 'scripts': '$userbase/Scripts', 'data' : '$userbase', }, 'unix_user': { + 'stdlib': '$userbase/lib/python/$py_version_short', + 'platstdlib': '$userbase/lib/python/$py_version_short', 'purelib': '$userbase/lib/python/$py_version_short/site-packages', 'platlib': '$userbase/lib/python/$py_version_short/site-packages', - 'headers': '$userbase/include/python$py_version_short/$dist_name', - 'scripts': '$userbase/bin', - 'data' : '$userbase', - }, - 'mac_user': { - 'purelib': '$userbase/lib/python/$py_version_short/site-packages', - 'platlib': '$userbase/lib/python/$py_version_short/site-packages', - 'headers': '$userbase/$py_version_short/include/$dist_name', + 'include': '$userbase/include/python$py_version_short', 'scripts': '$userbase/bin', 'data' : '$userbase', }, - 'os2_home': { - 'purelib': '$userbase/lib/python/$py_version_short/site-packages', - 'platlib': '$userbase/lib/python/$py_version_short/site-packages', - 'headers': '$userbase/include/python$py_version_short/$dist_name', - 'scripts': '$userbase/bin', - 'data' : '$userbase', - } } -_SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') _PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = sys.version[:3] +_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] _PREFIX = os.path.normpath(sys.prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) _CONFIG_VARS = None @@ -94,12 +101,10 @@ _PYTHON_BUILD = _python_build() -def get_python_version(): - """Return a string containing the major and minor Python version, - leaving off the patchlevel. Sample return values could be '1.5' - or '2.2'. - """ - return sys.version[:3] +if _PYTHON_BUILD: + for scheme in ('unix_prefix', 'unix_home'): + _INSTALL_SCHEMES[scheme]['include'] = '$projectbase' + _INSTALL_SCHEMES[scheme]['platinclude'] = '$srcdir/Include' def _subst_vars(s, local_vars): import re @@ -128,23 +133,8 @@ return 'unix_home' return os.name -def get_paths(scheme=_get_default_scheme(), vars=None): - """Returns a mapping containing the install scheme. - - ``scheme`` is the install scheme name - """ - return _expand_vars(scheme, vars) - -def get_path(scheme, name, vars=None): - """Returns a mapping containing the install scheme. - - ``scheme`` is the install scheme name - """ - return _expand_vars(scheme, vars)[name] - def _getuserbase(): env_base = os.environ.get("PYTHONUSERBASE", None) - def joinuser(*args): return os.path.expanduser(os.path.join(*args)) @@ -155,12 +145,205 @@ return env_base if env_base else joinuser("~", ".local") + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + import re + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with open(filename) as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + while notdone: + for name in notdone.keys(): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + else: + done[n] = item = "" + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + del notdone[name] + else: + # bogus variable reference; just drop it since we can't deal + del notdone[name] + # save the results in the global dictionary + vars.update(done) + return vars + +def _parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + import re + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: v = int(v) + except ValueError: pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + if _PYTHON_BUILD: + makefile = os.path.join(_PROJECT_BASE, "Makefile") + else: + makefile = os.path.join(get_path('stdlib'), "config", "Makefile") + try: + _parse_makefile(makefile, vars) + except IOError, e: + msg = "invalid Python installation: unable to open %s" % filename + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + + # load the installed pyconfig.h: + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + config_h = os.path.join(inc_dir, 'pyconfig.h') + try: + _parse_config_h(open(config_h), vars) + except IOError, e: + msg = "invalid Python installation: unable to open %s" % filename + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + + # On MacOSX we need to check the setting of the environment variable + # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so + # it needs to be compatible. + # If it isn't set we set it to the configure-time value + if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in vars: + cfg_target = vars['MACOSX_DEPLOYMENT_TARGET'] + cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') + if cur_target == '': + cur_target = cfg_target + os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target) + elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): + msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" ' + 'during configure' % (cur_target, cfg_target)) + raise IOError(msg) + + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) + +# +# public APIs +# +def get_paths(scheme=_get_default_scheme(), vars=None): + """Returns a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + return _expand_vars(scheme, vars) + +def get_path(name, scheme=_get_default_scheme(), vars=None): + """Returns a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return _expand_vars(scheme, vars)[name] + + def get_config_vars(*args): """With no arguments, return a dictionary of all configuration - variables relevant for the current platform. Generally this includes - everything needed to build extensions and install both pure modules and - extensions. On Unix, this means every variable defined in Python's - installed Makefile; on Windows and Mac OS it's a much smaller set. + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. @@ -168,11 +351,11 @@ import re global _CONFIG_VARS if _CONFIG_VARS is None: - func = globals().get("_init_" + os.name) - if func: - func() - else: - _CONFIG_VARS = {} + _CONFIG_VARS = {} + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) # Normalized versions of prefix and exec_prefix are handy to have; # in fact, these are the standard versions used most places in the @@ -180,12 +363,12 @@ _CONFIG_VARS['prefix'] = _PREFIX _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX _CONFIG_VARS['py_version'] = _PY_VERSION - _CONFIG_VARS['py_version_short'] = _PY_VERSION[3:0] + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] _CONFIG_VARS['base'] = _PREFIX _CONFIG_VARS['platbase'] = _EXEC_PREFIX _CONFIG_VARS['userbase'] = _getuserbase() - _CONFIG_VARS['dist_name'] = '' + _CONFIG_VARS['projectbase'] = _PROJECT_BASE if 'srcdir' not in _CONFIG_VARS: _CONFIG_VARS['srcdir'] = _PROJECT_BASE @@ -195,7 +378,7 @@ # testing, for example, we might be running a non-installed python # from a different directory. if _PYTHON_BUILD and os.name == "posix": - base = os.path.dirname(abspath(sys.executable)) + base = _PROJECT_BASE if (not os.path.isabs(_CONFIG_VARS['srcdir']) and base != os.getcwd()): # srcdir is relative and we are not in the same directory @@ -213,7 +396,6 @@ # 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', # a number of derived variables. These need to be # patched up as well. @@ -222,15 +404,12 @@ flags = re.sub('-arch\s+\w+\s', ' ', flags) flags = re.sub('-isysroot [^ \t]*', ' ', flags) _CONFIG_VARS[key] = flags - else: - # Allow the user to override the architecture flags using # an environment variable. # NOTE: This name was introduced by Apple in OSX 10.5 and # is used by several scripting languages distributed with # that OS release. - if 'ARCHFLAGS' in os.environ: arch = os.environ['ARCHFLAGS'] for key in ('LDFLAGS', 'BASECFLAGS', @@ -276,9 +455,10 @@ return _CONFIG_VARS def get_config_var(name): - """Return the value of a single variable using the dictionary - returned by 'get_CONFIG_VARS()'. Equivalent to - get_CONFIG_VARS().get(name) + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) """ return get_config_vars().get(name) @@ -307,6 +487,7 @@ For other non-POSIX platforms, currently just returns 'sys.platform'. """ + import re if os.name == 'nt': # sniff sys.version for architecture. prefix = " bit (" @@ -363,7 +544,6 @@ # machine is going to compile and link as if it were # MACOSX_DEPLOYMENT_TARGET. cfgvars = get_config_vars() - macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET') if not macver: macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') @@ -435,155 +615,3 @@ machine = 'ppc' return "%s-%s-%s" % (osname, release, machine) - - -def get_python_inc(plat_specific=0, prefix=None): - """Return the directory containing installed Python header files. - - If 'plat_specific' is false (the default), this is the path to the - non-platform-specific header files, i.e. Python.h and so on; - otherwise, this is the path to platform-specific header files - (namely pyconfig.h). - - If 'prefix' is supplied, use it instead of sys.prefix or - sys.exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - prefix = plat_specific and _EXEC_PREFIX or _PREFIX - if os.name == "posix": - if _PYTHON_BUILD: - # Assume the executable is in the build directory. The - # pyconfig.h file should be in the same directory. Since - # the build directory may not be the source directory, we - # must use "srcdir" from the makefile to find the "Include" - # directory. - base = os.path.dirname(os.path.abspath(sys.executable)) - if plat_specific: - return base - else: - incdir = os.path.join(get_config_var('srcdir'), 'Include') - return os.path.normpath(incdir) - return os.path.join(prefix, "include", "python" + get_python_version()) - elif os.name == "nt": - return os.path.join(prefix, "include") - elif os.name == "mac": - if plat_specific: - return os.path.join(prefix, "Mac", "Include") - else: - return os.path.join(prefix, "Include") - elif os.name == "os2": - return os.path.join(prefix, "Include") - else: - raise DistutilsPlatformError( - "I don't know where Python installs its C header files " - "on platform '%s'" % os.name) - -def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - """Return the directory containing the Python library (standard or - site additions). - - If 'plat_specific' is true, return the directory containing - platform-specific modules, i.e. any module from a non-pure-Python - module distribution; otherwise, return the platform-shared library - directory. If 'standard_lib' is true, return the directory - containing standard Python library modules; otherwise, return the - directory for site-specific modules. - - If 'prefix' is supplied, use it instead of sys.prefix or - sys.exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - prefix = plat_specific and _EXEC_PREFIX or _PREFIX - - if os.name == "posix": - libpython = os.path.join(prefix, - "lib", "python" + get_python_version()) - if standard_lib: - return libpython - else: - return os.path.join(libpython, "site-packages") - - elif os.name == "nt": - if standard_lib: - return os.path.join(prefix, "Lib") - else: - if get_python_version() < "2.2": - return prefix - else: - return os.path.join(prefix, "Lib", "site-packages") - - elif os.name == "mac": - if plat_specific: - if standard_lib: - return os.path.join(prefix, "Lib", "lib-dynload") - else: - return os.path.join(prefix, "Lib", "site-packages") - else: - if standard_lib: - return os.path.join(prefix, "Lib") - else: - return os.path.join(prefix, "Lib", "site-packages") - - elif os.name == "os2": - if standard_lib: - return os.path.join(prefix, "Lib") - else: - return os.path.join(prefix, "Lib", "site-packages") - - else: - raise DistutilsPlatformError( - "I don't know where Python installs its library " - "on platform '%s'" % os.name) - - -def get_config_h_filename(): - """Return full pathname of installed pyconfig.h file.""" - if _PYTHON_BUILD: - if os.name == "nt": - inc_dir = os.path.join(project_base, "PC") - else: - inc_dir = _PROJECT_BASE - else: - inc_dir = get_python_inc(plat_specific=1) - if get_python_version() < '2.2': - config_h = 'config.h' - else: - # The name of the config.h file changed in 2.2 - config_h = 'pyconfig.h' - return os.path.join(inc_dir, config_h) - - -def get_makefile_filename(): - """Return full pathname of installed Makefile from the Python build.""" - if _PYTHON_BUILD: - return os.path.join(os.path.dirname(sys.executable), "Makefile") - lib_dir = get_python_lib(plat_specific=1, standard_lib=1) - return os.path.join(lib_dir, "config", "Makefile") - -def parse_config_h(fp, g=None): - """Parse a config.h-style file. - - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - if g is None: - g = {} - define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") - # - while 1: - line = fp.readline() - if not line: - break - m = define_rx.match(line) - if m: - n, v = m.group(1, 2) - try: v = int(v) - except ValueError: pass - g[n] = v - else: - m = undef_rx.match(line) - if m: - g[m.group(1)] = 0 - return g Modified: python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Mon Nov 16 01:11:20 2009 @@ -8,9 +8,13 @@ import sys import test import os +from copy import copy, deepcopy + from test.test_support import run_unittest, TESTFN -from sysconfig import * -from sysconfig import _INSTALL_SCHEMES, _SCHEME_KEYS + +import sysconfig +from sysconfig import (get_paths, get_platform, get_config_vars, get_path, + _INSTALL_SCHEMES) class TestSysConfig(unittest.TestCase): @@ -19,6 +23,24 @@ super(TestSysConfig, self).setUp() self.sys_path = sys.path[:] self.makefile = None + # patching os.uname + if hasattr(os, 'uname'): + self.uname = os.uname + self._uname = os.uname() + else: + self.uname = None + self._uname = None + os.uname = self._get_uname + # saving the environment + self.name = os.name + self.platform = sys.platform + self.version = sys.version + self.sep = os.sep + self.join = os.path.join + self.isabs = os.path.isabs + self.splitdrive = os.path.splitdrive + self._config_vars = copy(sysconfig._CONFIG_VARS) + self.old_environ = deepcopy(os.environ) def tearDown(self): """Restore sys.path""" @@ -26,8 +48,34 @@ if self.makefile is not None: os.unlink(self.makefile) self._cleanup_testfn() + if self.uname is not None: + os.uname = self.uname + else: + del os.uname + os.name = self.name + sys.platform = self.platform + sys.version = self.version + os.sep = self.sep + os.path.join = self.join + os.path.isabs = self.isabs + os.path.splitdrive = self.splitdrive + sysconfig._CONFIG_VARS = copy(self._config_vars) + for key, value in self.old_environ.items(): + if os.environ.get(key) != value: + os.environ[key] = value + + for key in os.environ.keys(): + if key not in self.old_environ: + del os.environ[key] + super(TestSysConfig, self).tearDown() + def _set_uname(self, uname): + self._uname = uname + + def _get_uname(self): + return self._uname + def _cleanup_testfn(self): path = test.test_support.TESTFN if os.path.isfile(path): @@ -38,49 +86,125 @@ def test_get_paths(self): # XXX make it os independant scheme = get_paths() - wanted = {'purelib': '/usr/local/lib/python', - 'headers': '/usr/local/include/python/', - 'platlib': '/usr/local/lib/python', - 'data': '/usr/local', - 'scripts': '/usr/local/bin'} + wanted = [('data', '/usr/local'), + ('include', '/Users/tarek/Dev/svn.python.org/tarek_sysconfig'), + ('platinclude', './Include'), + ('platlib', '/usr/local/lib/python'), + ('platstdlib', '/usr/local/lib/python'), + ('purelib', '/usr/local/lib/python'), + ('scripts', '/usr/local/bin'), + ('stdlib', '/usr/local/lib/python')] - wanted = wanted.items() - wanted.sort() scheme = scheme.items() scheme.sort() self.assertEquals(scheme, wanted) def test_get_path(self): - for key in _INSTALL_SCHEMES: - for name in _SCHEME_KEYS: - res = get_path(key, name) - - def test_get_config_h_filename(self): - config_h = get_config_h_filename() - self.assertTrue(os.path.isfile(config_h), config_h) - - def test_get_python_lib(self): - lib_dir = get_python_lib() - # XXX doesn't work on Linux when Python was never installed before - #self.assertTrue(os.path.isdir(lib_dir), lib_dir) - # test for pythonxx.lib? - self.assertNotEqual(get_python_lib(), - get_python_lib(prefix=TESTFN)) - - def test_get_python_inc(self): - inc_dir = get_python_inc() - # This is not much of a test. We make sure Python.h exists - # in the directory returned by get_python_inc() but we don't know - # it is the correct file. - self.assertTrue(os.path.isdir(inc_dir), inc_dir) - python_h = os.path.join(inc_dir, "Python.h") - self.assertTrue(os.path.isfile(python_h), python_h) + # xxx make real tests here + for scheme in _INSTALL_SCHEMES: + for name in _INSTALL_SCHEMES[scheme]: + res = get_path(name, scheme) def test_get_config_vars(self): cvars = get_config_vars() self.assertTrue(isinstance(cvars, dict)) self.assertTrue(cvars) + def test_get_platform(self): + # windows XP, 32bits + os.name = 'nt' + sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' + '[MSC v.1310 32 bit (Intel)]') + sys.platform = 'win32' + self.assertEquals(get_platform(), 'win32') + + # windows XP, amd64 + os.name = 'nt' + sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' + '[MSC v.1310 32 bit (Amd64)]') + sys.platform = 'win32' + self.assertEquals(get_platform(), 'win-amd64') + + # windows XP, itanium + os.name = 'nt' + sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' + '[MSC v.1310 32 bit (Itanium)]') + sys.platform = 'win32' + self.assertEquals(get_platform(), 'win-ia64') + + # macbook + os.name = 'posix' + sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' + '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') + sys.platform = 'darwin' + self._set_uname(('Darwin', 'macziade', '8.11.1', + ('Darwin Kernel Version 8.11.1: ' + 'Wed Oct 10 18:23:28 PDT 2007; ' + 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) + get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + + get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' + '-fwrapv -O3 -Wall -Wstrict-prototypes') + + self.assertEquals(get_platform(), 'macosx-10.3-i386') + + # macbook with fat binaries (fat, universal or fat64) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.4' + get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-intel') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + self.assertEquals(get_platform(), 'macosx-10.4-fat3') + + get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + self.assertEquals(get_platform(), 'macosx-10.4-universal') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat64') + + for arch in ('ppc', 'i386', 'x86_64', 'ppc64'): + get_config_vars()['CFLAGS'] = ('-arch %s -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3'%(arch,)) + + self.assertEquals(get_platform(), 'macosx-10.4-%s'%(arch,)) + + # linux debian sarge + os.name = 'posix' + sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' + '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]') + sys.platform = 'linux2' + self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7', + '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686')) + + self.assertEquals(get_platform(), 'linux-i686') + + # XXX more platforms to tests here + + def test_main(): run_unittest(TestSysConfig) From python-checkins at python.org Mon Nov 16 01:22:22 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 16 Nov 2009 00:22:22 -0000 Subject: [Python-checkins] r76317 - in python/branches/tarek_sysconfig/Lib: sysconfig.py test/test_sysconfig.py Message-ID: Author: tarek.ziade Date: Mon Nov 16 01:22:22 2009 New Revision: 76317 Log: added a list of the scheme keys Modified: python/branches/tarek_sysconfig/Lib/sysconfig.py python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Modified: python/branches/tarek_sysconfig/Lib/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/sysconfig.py Mon Nov 16 01:22:22 2009 @@ -75,6 +75,8 @@ }, } +_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', + 'scripts', 'data') _PY_VERSION = sys.version.split()[0] _PY_VERSION_SHORT = sys.version[:3] _PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] @@ -322,6 +324,9 @@ # # public APIs # +def get_path_names(): + return _SCHEME_KEYS + def get_paths(scheme=_get_default_scheme(), vars=None): """Returns a mapping containing an install scheme. @@ -337,7 +342,6 @@ """ return _expand_vars(scheme, vars)[name] - def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. Modified: python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/test/test_sysconfig.py Mon Nov 16 01:22:22 2009 @@ -13,8 +13,8 @@ from test.test_support import run_unittest, TESTFN import sysconfig -from sysconfig import (get_paths, get_platform, get_config_vars, get_path, - _INSTALL_SCHEMES) +from sysconfig import (get_paths, get_platform, get_config_vars, + get_path, get_path_names, _INSTALL_SCHEMES) class TestSysConfig(unittest.TestCase): @@ -83,6 +83,9 @@ elif os.path.isdir(path): shutil.rmtree(path) + def test_get_path_names(self): + self.assertEquals(get_path_names(), sysconfig._SCHEME_KEYS) + def test_get_paths(self): # XXX make it os independant scheme = get_paths() From python-checkins at python.org Mon Nov 16 01:25:02 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 16 Nov 2009 00:25:02 -0000 Subject: [Python-checkins] r76318 - python/branches/py3k/Lib/test/test_range.py Message-ID: Author: benjamin.peterson Date: Mon Nov 16 01:25:02 2009 New Revision: 76318 Log: remove 2.x specific warnings Modified: python/branches/py3k/Lib/test/test_range.py Modified: python/branches/py3k/Lib/test/test_range.py ============================================================================== --- python/branches/py3k/Lib/test/test_range.py (original) +++ python/branches/py3k/Lib/test/test_range.py Mon Nov 16 01:25:02 2009 @@ -5,10 +5,6 @@ import pickle import itertools -import warnings -warnings.filterwarnings("ignore", "integer argument expected", - DeprecationWarning, "unittest") - # pure Python implementations (3 args only), for comparison def pyrange(start, stop, step): if (start - stop) // step < 0: From python-checkins at python.org Mon Nov 16 01:34:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 16 Nov 2009 00:34:25 -0000 Subject: [Python-checkins] r76319 - python/branches/py3k/Objects/rangeobject.c Message-ID: Author: benjamin.peterson Date: Mon Nov 16 01:34:25 2009 New Revision: 76319 Log: fix one visible and several possible refleaks in rangeobject.c In some cases, the code was just reordered to allow for less decrefing. Modified: python/branches/py3k/Objects/rangeobject.c Modified: python/branches/py3k/Objects/rangeobject.c ============================================================================== --- python/branches/py3k/Objects/rangeobject.c (original) +++ python/branches/py3k/Objects/rangeobject.c Mon Nov 16 01:34:25 2009 @@ -533,6 +533,7 @@ it->step = step; ulen = get_len_of_range(start, stop, step); if (ulen > (unsigned long)LONG_MAX) { + Py_DECREF(it); PyErr_SetString(PyExc_OverflowError, "range too large to represent as a range_iterator"); return NULL; @@ -584,16 +585,14 @@ if (!one) return NULL; - product = PyNumber_Multiply(r->index, r->step); - if (!product) { - Py_DECREF(one); - return NULL; - } - new_index = PyNumber_Add(r->index, one); Py_DECREF(one); - if (!new_index) { - Py_DECREF(product); + if (!new_index) + return NULL; + + product = PyNumber_Multiply(r->index, r->step); + if (!product) { + Py_DECREF(new_index); return NULL; } @@ -603,6 +602,9 @@ Py_DECREF(r->index); r->index = new_index; } + else { + Py_DECREF(new_index); + } return result; } @@ -781,6 +783,9 @@ if (!len) goto create_failure; + /* Steal reference to len. */ + it->len = len; + one = PyLong_FromLong(1); if (!one) goto create_failure; @@ -802,24 +807,16 @@ goto create_failure; it->step = PyNumber_Negative(range->step); - if (!it->step) { - Py_DECREF(it->start); + if (!it->step) goto create_failure; - } - - /* Steal reference to len. */ - it->len = len; it->index = PyLong_FromLong(0); - if (!it->index) { - Py_DECREF(it); - return NULL; - } + if (!it->index) + goto create_failure; return (PyObject *)it; create_failure: - Py_XDECREF(len); - PyObject_Del(it); + Py_DECREF(it); return NULL; } From python-checkins at python.org Mon Nov 16 01:36:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 16 Nov 2009 00:36:18 -0000 Subject: [Python-checkins] r76320 - in python/branches/release31-maint: Objects/rangeobject.c Message-ID: Author: benjamin.peterson Date: Mon Nov 16 01:36:18 2009 New Revision: 76320 Log: Merged revisions 76319 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76319 | benjamin.peterson | 2009-11-15 18:34:25 -0600 (Sun, 15 Nov 2009) | 4 lines fix one visible and several possible refleaks in rangeobject.c In some cases, the code was just reordered to allow for less decrefing. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Objects/rangeobject.c Modified: python/branches/release31-maint/Objects/rangeobject.c ============================================================================== --- python/branches/release31-maint/Objects/rangeobject.c (original) +++ python/branches/release31-maint/Objects/rangeobject.c Mon Nov 16 01:36:18 2009 @@ -476,6 +476,7 @@ it->step = step; ulen = get_len_of_range(start, stop, step); if (ulen > (unsigned long)LONG_MAX) { + Py_DECREF(it); PyErr_SetString(PyExc_OverflowError, "range too large to represent as a range_iterator"); return NULL; @@ -527,16 +528,14 @@ if (!one) return NULL; - product = PyNumber_Multiply(r->index, r->step); - if (!product) { - Py_DECREF(one); - return NULL; - } - new_index = PyNumber_Add(r->index, one); Py_DECREF(one); - if (!new_index) { - Py_DECREF(product); + if (!new_index) + return NULL; + + product = PyNumber_Multiply(r->index, r->step); + if (!product) { + Py_DECREF(new_index); return NULL; } @@ -546,6 +545,9 @@ Py_DECREF(r->index); r->index = new_index; } + else { + Py_DECREF(new_index); + } return result; } @@ -724,6 +726,9 @@ if (!len) goto create_failure; + /* Steal reference to len. */ + it->len = len; + one = PyLong_FromLong(1); if (!one) goto create_failure; @@ -745,24 +750,16 @@ goto create_failure; it->step = PyNumber_Negative(range->step); - if (!it->step) { - Py_DECREF(it->start); + if (!it->step) goto create_failure; - } - - /* Steal reference to len. */ - it->len = len; it->index = PyLong_FromLong(0); - if (!it->index) { - Py_DECREF(it); - return NULL; - } + if (!it->index) + goto create_failure; return (PyObject *)it; create_failure: - Py_XDECREF(len); - PyObject_Del(it); + Py_DECREF(it); return NULL; } From python-checkins at python.org Mon Nov 16 04:55:51 2009 From: python-checkins at python.org (nick.coghlan) Date: Mon, 16 Nov 2009 03:55:51 -0000 Subject: [Python-checkins] r76321 - python/trunk/Lib/test/regrtest.py Message-ID: Author: nick.coghlan Date: Mon Nov 16 04:55:51 2009 New Revision: 76321 Log: Account for another cache when hunting ref leaks Modified: python/trunk/Lib/test/regrtest.py Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Mon Nov 16 04:55:51 2009 @@ -948,6 +948,12 @@ fs = warnings.filters[:] ps = copy_reg.dispatch_table.copy() pic = sys.path_importer_cache.copy() + try: + import zipimport + except ImportError: + zdc = None # Run unmodified on platforms without zipimport support + else: + zdc = zipimport._zip_directory_cache.copy() abcs = {} modules = _abcoll, _pyio for abc in [getattr(mod, a) for mod in modules for a in mod.__all__]: @@ -969,12 +975,12 @@ repcount = nwarmup + ntracked print >> sys.stderr, "beginning", repcount, "repetitions" print >> sys.stderr, ("1234567890"*(repcount//10 + 1))[:repcount] - dash_R_cleanup(fs, ps, pic, abcs) + dash_R_cleanup(fs, ps, pic, zdc, abcs) for i in range(repcount): rc = sys.gettotalrefcount() run_the_test() sys.stderr.write('.') - dash_R_cleanup(fs, ps, pic, abcs) + dash_R_cleanup(fs, ps, pic, zdc, abcs) if i >= nwarmup: deltas.append(sys.gettotalrefcount() - rc - 2) print >> sys.stderr @@ -987,7 +993,7 @@ return True return False -def dash_R_cleanup(fs, ps, pic, abcs): +def dash_R_cleanup(fs, ps, pic, zdc, abcs): import gc, copy_reg import _strptime, linecache dircache = test_support.import_module('dircache', deprecated=True) @@ -1006,6 +1012,13 @@ copy_reg.dispatch_table.update(ps) sys.path_importer_cache.clear() sys.path_importer_cache.update(pic) + try: + import zipimport + except ImportError: + pass # Run unmodified on platforms without zipimport support + else: + zipimport._zip_directory_cache.clear() + zipimport._zip_directory_cache.update(zdc) # clear type cache sys._clear_type_cache() From python-checkins at python.org Mon Nov 16 04:57:32 2009 From: python-checkins at python.org (nick.coghlan) Date: Mon, 16 Nov 2009 03:57:32 -0000 Subject: [Python-checkins] r76322 - python/trunk/Lib/test/test_runpy.py Message-ID: Author: nick.coghlan Date: Mon Nov 16 04:57:32 2009 New Revision: 76322 Log: Allow for backslashes in file paths passed to the regex engine Modified: python/trunk/Lib/test/test_runpy.py Modified: python/trunk/Lib/test/test_runpy.py ============================================================================== --- python/trunk/Lib/test/test_runpy.py (original) +++ python/trunk/Lib/test/test_runpy.py Mon Nov 16 04:57:32 2009 @@ -317,6 +317,8 @@ self.assertEqual(result["__package__"], expected_package) def _check_import_error(self, script_name, msg): + # Double backslashes to handle path separators on Windows + msg = msg.replace("\\", "\\\\") self.assertRaisesRegexp(ImportError, msg, run_path, script_name) def test_basic_script(self): From python-checkins at python.org Mon Nov 16 05:01:51 2009 From: python-checkins at python.org (nick.coghlan) Date: Mon, 16 Nov 2009 04:01:51 -0000 Subject: [Python-checkins] r76323 - python/branches/release26-maint Message-ID: Author: nick.coghlan Date: Mon Nov 16 05:01:51 2009 New Revision: 76323 Log: Blocked revisions 76321-76322 via svnmerge ........ r76321 | nick.coghlan | 2009-11-16 13:55:51 +1000 (Mon, 16 Nov 2009) | 1 line Account for another cache when hunting ref leaks ........ r76322 | nick.coghlan | 2009-11-16 13:57:32 +1000 (Mon, 16 Nov 2009) | 1 line Allow for backslashes in file paths passed to the regex engine ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 16 07:49:26 2009 From: python-checkins at python.org (nick.coghlan) Date: Mon, 16 Nov 2009 06:49:26 -0000 Subject: [Python-checkins] r76324 - in python/branches/py3k: Doc/library/runpy.rst Lib/runpy.py Lib/test/regrtest.py Lib/test/script_helper.py Lib/test/test_cmd_line.py Lib/test/test_cmd_line_script.py Lib/test/test_runpy.py Lib/test/test_zipimport_support.py Misc/NEWS Message-ID: Author: nick.coghlan Date: Mon Nov 16 07:49:25 2009 New Revision: 76324 Log: Merged revisions 76286-76287,76289-76294,76296-76299,76301-76305,76307,76310-76311,76313-76322 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76286 | nick.coghlan | 2009-11-15 17:30:34 +1000 (Sun, 15 Nov 2009) | 1 line Issue #6816: expose the zipfile and directory execution mechanism to Python code via the runpy module. Also consolidated some script execution functionality in the test harness into a helper module and removed some implementation details from the runpy module documentation. ........ r76321 | nick.coghlan | 2009-11-16 13:55:51 +1000 (Mon, 16 Nov 2009) | 1 line Account for another cache when hunting ref leaks ........ r76322 | nick.coghlan | 2009-11-16 13:57:32 +1000 (Mon, 16 Nov 2009) | 1 line Allow for backslashes in file paths passed to the regex engine ........ Added: python/branches/py3k/Lib/test/script_helper.py (contents, props changed) Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/runpy.rst python/branches/py3k/Lib/runpy.py python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/test_cmd_line.py python/branches/py3k/Lib/test/test_cmd_line_script.py python/branches/py3k/Lib/test/test_runpy.py python/branches/py3k/Lib/test/test_zipimport_support.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/runpy.rst ============================================================================== --- python/branches/py3k/Doc/library/runpy.rst (original) +++ python/branches/py3k/Doc/library/runpy.rst Mon Nov 16 07:49:25 2009 @@ -7,70 +7,122 @@ The :mod:`runpy` module is used to locate and run Python modules without -importing them first. Its main use is to implement the :option:`-m` command line -switch that allows scripts to be located using the Python module namespace -rather than the filesystem. +importing them first. Its main use is to implement the :option:`-m` command +line switch that allows scripts to be located using the Python module +namespace rather than the filesystem. -When executed as a script, the module effectively operates as follows:: - - del sys.argv[0] # Remove the runpy module from the arguments - run_module(sys.argv[0], run_name="__main__", alter_sys=True) - -The :mod:`runpy` module provides a single function: +The :mod:`runpy` module provides two functions: .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) - Execute the code of the specified module and return the resulting module globals - dictionary. The module's code is first located using the standard import - mechanism (refer to PEP 302 for details) and then executed in a fresh module - namespace. - - If the supplied module name refers to a package rather than a normal module, - then that package is imported and the ``__main__`` submodule within that - package is then executed and the resulting module globals dictionary returned. - - The optional dictionary argument *init_globals* may be used to pre-populate the - globals dictionary before the code is executed. The supplied dictionary will not - be modified. If any of the special global variables below are defined in the - supplied dictionary, those definitions are overridden by the ``run_module`` - function. - - The special global variables ``__name__``, ``__file__``, ``__loader__``, - ``__builtins__`` and ``__package__`` are set in the globals dictionary before - the module code is executed. - - ``__name__`` is set to *run_name* if this optional argument is supplied, to - ``mod_name + '.__main__'`` if the named module is a package and to the - *mod_name* argument otherwise. - - ``__loader__`` is set to the PEP 302 module loader used to retrieve the code for - the module (This loader may be a wrapper around the standard import mechanism). - - ``__file__`` is set to the name provided by the module loader. If the loader - does not make filename information available, this variable is set to ``None``. - - ``__builtins__`` is automatically initialised with a reference to the top level - namespace of the :mod:`builtins` module. + Execute the code of the specified module and return the resulting module + globals dictionary. The module's code is first located using the standard + import mechanism (refer to PEP 302 for details) and then executed in a + fresh module namespace. + + If the supplied module name refers to a package rather than a normal + module, then that package is imported and the ``__main__`` submodule within + that package is then executed and the resulting module globals dictionary + returned. + + The optional dictionary argument *init_globals* may be used to pre-populate + the module's globals dictionary before the code is executed. The supplied + dictionary will not be modified. If any of the special global variables + below are defined in the supplied dictionary, those definitions are + overridden by :func:`run_module`. + + The special global variables ``__name__``, ``__file__``, ``__loader__`` + and ``__package__`` are set in the globals dictionary before the module + code is executed (Note that this is a minimal set of variables - other + variables may be set implicitly as an interpreter implementation detail). + + ``__name__`` is set to *run_name* if this optional argument is not + :const:`None`, to ``mod_name + '.__main__'`` if the named module is a + package and to the *mod_name* argument otherwise. + + ``__file__`` is set to the name provided by the module loader. If the + loader does not make filename information available, this variable is set + to `:const:`None`. + + ``__loader__`` is set to the PEP 302 module loader used to retrieve the + code for the module (This loader may be a wrapper around the standard + import mechanism). - ``__package__`` is set to *mod_name* if the named module is a package and to - ``mod_name.rpartition('.')[0]`` otherwise. + ``__package__`` is set to *mod_name* if the named module is a package and + to ``mod_name.rpartition('.')[0]`` otherwise. - If the argument *alter_sys* is supplied and evaluates to ``True``, then - ``sys.argv[0]`` is updated with the value of ``__file__`` and + If the argument *alter_sys* is supplied and evaluates to :const:`True`, + then ``sys.argv[0]`` is updated with the value of ``__file__`` and ``sys.modules[__name__]`` is updated with a temporary module object for the module being executed. Both ``sys.argv[0]`` and ``sys.modules[__name__]`` are restored to their original values before the function returns. - Note that this manipulation of :mod:`sys` is not thread-safe. Other threads may - see the partially initialised module, as well as the altered list of arguments. - It is recommended that the :mod:`sys` module be left alone when invoking this - function from threaded code. + Note that this manipulation of :mod:`sys` is not thread-safe. Other threads + may see the partially initialised module, as well as the altered list of + arguments. It is recommended that the :mod:`sys` module be left alone when + invoking this function from threaded code. .. versionchanged:: 3.1 - Added ability to execute packages by looking for a ``__main__`` submodule + Added ability to execute packages by looking for a ``__main__`` + submodule + + +.. function:: run_path(file_path, init_globals=None, run_name=None) + + Execute the code at the named filesystem location and return the resulting + module globals dictionary. As with a script name supplied to the CPython + command line, the supplied path may refer to a Python source file, a + compiled bytecode file or a valid sys.path entry containing a ``__main__`` + module (e.g. a zipfile containing a top-level ``__main__.py`` file). + + For a simple script, the specified code is simply executed in a fresh + module namespace. For a valid sys.path entry (typically a zipfile or + directory), the entry is first added to the beginning of ``sys.path``. The + function then looks for and executes a :mod:`__main__` module using the + updated path. Note that there is no special protection against invoking + an existing :mod:`__main__` entry located elsewhere on ``sys.path`` if + there is no such module at the specified location. + + The optional dictionary argument *init_globals* may be used to pre-populate + the module's globals dictionary before the code is executed. The supplied + dictionary will not be modified. If any of the special global variables + below are defined in the supplied dictionary, those definitions are + overridden by :func:`run_path`. + + The special global variables ``__name__``, ``__file__``, ``__loader__`` + and ``__package__`` are set in the globals dictionary before the module + code is executed (Note that this is a minimal set of variables - other + variables may be set implicitly as an interpreter implementation detail). + + ``__name__`` is set to *run_name* if this optional argument is not + :const:`None` and to ``''`` otherwise. + + ``__file__`` is set to the name provided by the module loader. If the + loader does not make filename information available, this variable is set + to :const:`None`. For a simple script, this will be set to ``file_path``. + + ``__loader__`` is set to the PEP 302 module loader used to retrieve the + code for the module (This loader may be a wrapper around the standard + import mechanism). For a simple script, this will be set to :const:`None`. + + ``__package__`` is set to ``__name__.rpartition('.')[0]``. + + A number of alterations are also made to the :mod:`sys` module. Firstly, + ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated + with the value of ``file_path`` and ``sys.modules[__name__]`` is updated + with a temporary module object for the module being executed. All + modifications to items in :mod:`sys` are reverted before the function + returns. + + Note that, unlike :func:`run_module`, the alterations made to :mod:`sys` + are not optional in this function as these adjustments are essential to + allowing the execution of sys.path entries. As the thread safety + limitations still apply, use of this function in threaded code should be + either serialised with the import lock or delegated to a separate process. + .. versionadded:: 3.2 .. seealso:: @@ -80,3 +132,4 @@ :pep:`366` - Main module explicit relative imports PEP written and implemented by Nick Coghlan. + :ref:`using-on-general` - CPython command line details Modified: python/branches/py3k/Lib/runpy.py ============================================================================== --- python/branches/py3k/Lib/runpy.py (original) +++ python/branches/py3k/Lib/runpy.py Mon Nov 16 07:49:25 2009 @@ -11,15 +11,53 @@ import sys import imp +from pkgutil import read_code try: from imp import get_loader except ImportError: from pkgutil import get_loader __all__ = [ - "run_module", + "run_module", "run_path", ] +class _TempModule(object): + """Temporarily replace a module in sys.modules with an empty namespace""" + def __init__(self, mod_name): + self.mod_name = mod_name + self.module = imp.new_module(mod_name) + self._saved_module = [] + + def __enter__(self): + mod_name = self.mod_name + try: + self._saved_module.append(sys.modules[mod_name]) + except KeyError: + pass + sys.modules[mod_name] = self.module + return self + + def __exit__(self, *args): + if self._saved_module: + sys.modules[self.mod_name] = self._saved_module[0] + else: + del sys.modules[self.mod_name] + self._saved_module = [] + +class _ModifiedArgv0(object): + def __init__(self, value): + self.value = value + self._saved_value = self._sentinel = object() + + def __enter__(self): + if self._saved_value is not self._sentinel: + raise RuntimeError("Already preserving saved value") + self._saved_value = sys.argv[0] + sys.argv[0] = self.value + + def __exit__(self, *args): + self.value = self._sentinel + sys.argv[0] = self._saved_value def _run_code(code, run_globals, init_globals=None, mod_name=None, mod_fname=None, @@ -38,26 +76,10 @@ mod_name=None, mod_fname=None, mod_loader=None, pkg_name=None): """Helper for run_module""" - # Set up the top level namespace dictionary - temp_module = imp.new_module(mod_name) - mod_globals = temp_module.__dict__ - # Modify sys.argv[0] and sys.module[mod_name] - saved_argv0 = sys.argv[0] - restore_module = mod_name in sys.modules - if restore_module: - saved_module = sys.modules[mod_name] - sys.argv[0] = mod_fname - sys.modules[mod_name] = temp_module - try: + with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname): + mod_globals = temp_module.module.__dict__ _run_code(code, mod_globals, init_globals, - mod_name, mod_fname, - mod_loader, pkg_name) - finally: - sys.argv[0] = saved_argv0 - if restore_module: - sys.modules[mod_name] = saved_module - else: - del sys.modules[mod_name] + mod_name, mod_fname, mod_loader, pkg_name) # Copy the globals of the temporary module, as they # may be cleared when the temporary module goes away return mod_globals.copy() @@ -95,11 +117,23 @@ return mod_name, loader, code, filename -# XXX ncoghlan: Should this be documented and made public? -# (Current thoughts: don't repeat the mistake that lead to its -# creation when run_module() no longer met the needs of -# mainmodule.c, but couldn't be changed because it was public) -def _run_module_as_main(mod_name, set_argv0=True): +def _get_main_module_details(): + # Helper that gives a nicer error message when attempting to + # execute a zipfile or directory by invoking __main__.py + main_name = "__main__" + try: + return _get_module_details(main_name) + except ImportError as exc: + if main_name in str(exc): + raise ImportError("can't find %r module in %r" % + (main_name, sys.path[0])) + raise + +# This function is the actual implementation of the -m switch and direct +# execution of zipfiles and directories and is deliberately kept private. +# This avoids a repeat of the situation where run_module() no longer met the +# needs of mainmodule.c, but couldn't be changed because it was public +def _run_module_as_main(mod_name, alter_argv=True): """Runs the designated module in the __main__ namespace These __*__ magic variables will be overwritten: @@ -107,22 +141,16 @@ __loader__ """ try: - mod_name, loader, code, fname = _get_module_details(mod_name) + if alter_argv or mod_name != "__main__": # i.e. -m switch + mod_name, loader, code, fname = _get_module_details(mod_name) + else: # i.e. directory or zipfile execution + mod_name, loader, code, fname = _get_main_module_details() except ImportError as exc: - # Try to provide a good error message - # for directories, zip files and the -m switch - if set_argv0: - # For -m switch, just display the exception - info = str(exc) - else: - # For directories/zipfiles, let the user - # know what the code was looking for - info = "can't find '__main__.py' in %r" % sys.argv[0] - msg = "%s: %s" % (sys.executable, info) + msg = "%s: %s" % (sys.executable, str(exc)) sys.exit(msg) pkg_name = mod_name.rpartition('.')[0] main_globals = sys.modules["__main__"].__dict__ - if set_argv0: + if alter_argv: sys.argv[0] = fname return _run_code(code, main_globals, None, "__main__", fname, loader, pkg_name) @@ -146,6 +174,95 @@ fname, loader, pkg_name) +# XXX (ncoghlan): Perhaps expose the C API function +# as imp.get_importer instead of reimplementing it in Python? +def _get_importer(path_name): + """Python version of PyImport_GetImporter C API function""" + cache = sys.path_importer_cache + try: + importer = cache[path_name] + except KeyError: + # Not yet cached. Flag as using the + # standard machinery until we finish + # checking the hooks + cache[path_name] = None + for hook in sys.path_hooks: + try: + importer = hook(path_name) + break + except ImportError: + pass + else: + # The following check looks a bit odd. The trick is that + # NullImporter throws ImportError if the supplied path is a + # *valid* directory entry (and hence able to be handled + # by the standard import machinery) + try: + importer = imp.NullImporter(path_name) + except ImportError: + return None + cache[path_name] = importer + return importer + +def _get_code_from_file(fname): + # Check for a compiled file first + with open(fname, "rb") as f: + code = read_code(f) + if code is None: + # That didn't work, so try it as normal source code + with open(fname, "rU") as f: + code = compile(f.read(), fname, 'exec') + return code + +def run_path(path_name, init_globals=None, run_name=None): + """Execute code located at the specified filesystem location + + Returns the resulting top level namespace dictionary + + The file path may refer directly to a Python script (i.e. + one that could be directly executed with execfile) or else + it may refer to a zipfile or directory containing a top + level __main__.py script. + """ + if run_name is None: + run_name = "" + importer = _get_importer(path_name) + if isinstance(importer, imp.NullImporter): + # Not a valid sys.path entry, so run the code directly + # execfile() doesn't help as we want to allow compiled files + code = _get_code_from_file(path_name) + return _run_module_code(code, init_globals, run_name, path_name) + else: + # Importer is defined for path, so add it to + # the start of sys.path + sys.path.insert(0, path_name) + try: + # Here's where things are a little different from the run_module + # case. There, we only had to replace the module in sys while the + # code was running and doing so was somewhat optional. Here, we + # have no choice and we have to remove it even while we read the + # code. If we don't do this, a __loader__ attribute in the + # existing __main__ module may prevent location of the new module. + main_name = "__main__" + saved_main = sys.modules[main_name] + del sys.modules[main_name] + try: + mod_name, loader, code, fname = _get_main_module_details() + finally: + sys.modules[main_name] = saved_main + pkg_name = "" + with _TempModule(run_name) as temp_module, \ + _ModifiedArgv0(path_name): + mod_globals = temp_module.module.__dict__ + return _run_code(code, mod_globals, init_globals, + run_name, fname, loader, pkg_name) + finally: + try: + sys.path.remove(path_name) + except ValueError: + pass + + if __name__ == "__main__": # Run the module specified as the next command line argument if len(sys.argv) < 2: Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Mon Nov 16 07:49:25 2009 @@ -957,6 +957,12 @@ fs = warnings.filters[:] ps = copyreg.dispatch_table.copy() pic = sys.path_importer_cache.copy() + try: + import zipimport + except ImportError: + zdc = None # Run unmodified on platforms without zipimport support + else: + zdc = zipimport._zip_directory_cache.copy() abcs = {} for abc in [getattr(_abcoll, a) for a in _abcoll.__all__]: if not isabstract(abc): @@ -978,13 +984,13 @@ print("beginning", repcount, "repetitions", file=sys.stderr) print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr) sys.stderr.flush() - dash_R_cleanup(fs, ps, pic, abcs) + dash_R_cleanup(fs, ps, pic, zdc, abcs) for i in range(repcount): rc = sys.gettotalrefcount() run_the_test() sys.stderr.write('.') sys.stderr.flush() - dash_R_cleanup(fs, ps, pic, abcs) + dash_R_cleanup(fs, ps, pic, zdc, abcs) if i >= nwarmup: deltas.append(sys.gettotalrefcount() - rc - 2) print(file=sys.stderr) @@ -998,7 +1004,7 @@ return True return False -def dash_R_cleanup(fs, ps, pic, abcs): +def dash_R_cleanup(fs, ps, pic, zdc, abcs): import gc, copyreg import _strptime, linecache import urllib.parse, urllib.request, mimetypes, doctest @@ -1017,6 +1023,13 @@ copyreg.dispatch_table.update(ps) sys.path_importer_cache.clear() sys.path_importer_cache.update(pic) + try: + import zipimport + except ImportError: + pass # Run unmodified on platforms without zipimport support + else: + zipimport._zip_directory_cache.clear() + zipimport._zip_directory_cache.update(zdc) # clear type cache sys._clear_type_cache() Added: python/branches/py3k/Lib/test/script_helper.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/script_helper.py Mon Nov 16 07:49:25 2009 @@ -0,0 +1,119 @@ +# Common utility functions used by various script execution tests +# e.g. test_cmd_line, test_cmd_line_script and test_runpy + +import sys +import os +import os.path +import tempfile +import subprocess +import py_compile +import contextlib +import shutil +import zipfile + +# Executing the interpreter in a subprocess +def python_exit_code(*args): + cmd_line = [sys.executable, '-E'] + cmd_line.extend(args) + with open(os.devnull, 'w') as devnull: + return subprocess.call(cmd_line, stdout=devnull, + stderr=subprocess.STDOUT) + +def spawn_python(*args): + cmd_line = [sys.executable, '-E'] + cmd_line.extend(args) + return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + +def kill_python(p): + p.stdin.close() + data = p.stdout.read() + p.stdout.close() + # try to cleanup the child so we don't appear to leak when running + # with regrtest -R. This should be a no-op on Windows. + subprocess._cleanup() + return data + +def run_python(*args): + if __debug__: + p = spawn_python(*args) + else: + p = spawn_python('-O', *args) + stdout_data = kill_python(p) + return p.wait(), stdout_data + +# Script creation utilities + at contextlib.contextmanager +def temp_dir(): + dirname = tempfile.mkdtemp() + dirname = os.path.realpath(dirname) + try: + yield dirname + finally: + shutil.rmtree(dirname) + +def make_script(script_dir, script_basename, source): + script_filename = script_basename+os.extsep+'py' + script_name = os.path.join(script_dir, script_filename) + script_file = open(script_name, 'w') + script_file.write(source) + script_file.close() + return script_name + +def compile_script(script_name): + py_compile.compile(script_name, doraise=True) + if __debug__: + compiled_name = script_name + 'c' + else: + compiled_name = script_name + 'o' + return compiled_name + +def make_zip_script(zip_dir, zip_basename, script_name, name_in_zip=None): + zip_filename = zip_basename+os.extsep+'zip' + zip_name = os.path.join(zip_dir, zip_filename) + zip_file = zipfile.ZipFile(zip_name, 'w') + if name_in_zip is None: + name_in_zip = os.path.basename(script_name) + zip_file.write(script_name, name_in_zip) + zip_file.close() + #if test.test_support.verbose: + # zip_file = zipfile.ZipFile(zip_name, 'r') + # print 'Contents of %r:' % zip_name + # zip_file.printdir() + # zip_file.close() + return zip_name, os.path.join(zip_name, name_in_zip) + +def make_pkg(pkg_dir): + os.mkdir(pkg_dir) + make_script(pkg_dir, '__init__', '') + +def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth=1, compiled=False): + unlink = [] + init_name = make_script(zip_dir, '__init__', '') + unlink.append(init_name) + init_basename = os.path.basename(init_name) + script_name = make_script(zip_dir, script_basename, source) + unlink.append(script_name) + if compiled: + init_name = compile_script(init_name) + script_name = compile_script(script_name) + unlink.extend((init_name, script_name)) + pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] + script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) + zip_filename = zip_basename+os.extsep+'zip' + zip_name = os.path.join(zip_dir, zip_filename) + zip_file = zipfile.ZipFile(zip_name, 'w') + for name in pkg_names: + init_name_in_zip = os.path.join(name, init_basename) + zip_file.write(init_name, init_name_in_zip) + zip_file.write(script_name, script_name_in_zip) + zip_file.close() + for name in unlink: + os.unlink(name) + #if test.test_support.verbose: + # zip_file = zipfile.ZipFile(zip_name, 'r') + # print 'Contents of %r:' % zip_name + # zip_file.printdir() + # zip_file.close() + return zip_name, os.path.join(zip_name, script_name_in_zip) Modified: python/branches/py3k/Lib/test/test_cmd_line.py ============================================================================== --- python/branches/py3k/Lib/test/test_cmd_line.py (original) +++ python/branches/py3k/Lib/test/test_cmd_line.py Mon Nov 16 07:49:25 2009 @@ -6,44 +6,41 @@ import test.support, unittest import os import sys -import subprocess +from test.script_helper import spawn_python, kill_python, python_exit_code -def _spawn_python(*args): +# XXX (ncoghlan): there are assorted gratuitous inconsistencies between the +# support code in the Py3k version and the 2.x version that unnecessarily +# complicate test suite merges. See issue 7331 + +# spawn_python normally enforces use of -E to avoid environmental effects +# but one test checks PYTHONPATH behaviour explicitly +# XXX (ncoghlan): Give script_helper.spawn_python an option to switch +# off the -E flag that is normally inserted automatically +import subprocess +def _spawn_python_with_env(*args): cmd_line = [sys.executable] - # When testing -S, we need PYTHONPATH to work (see test_site_flag()) - if '-S' not in args: - cmd_line.append('-E') cmd_line.extend(args) return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -def _kill_python(p): - return _kill_python_and_exit_code(p)[0] +# XXX (ncoghlan): Move to script_helper and make consistent with run_python def _kill_python_and_exit_code(p): - p.stdin.close() - data = p.stdout.read() - p.stdout.close() - # try to cleanup the child so we don't appear to leak when running - # with regrtest -R. This should be a no-op on Windows. - subprocess._cleanup() + data = kill_python(p) returncode = p.wait() return data, returncode class CmdLineTest(unittest.TestCase): def start_python(self, *args): - return self.start_python_and_exit_code(*args)[0] + p = spawn_python(*args) + return kill_python(p) def start_python_and_exit_code(self, *args): - p = _spawn_python(*args) + p = spawn_python(*args) return _kill_python_and_exit_code(p) def exit_code(self, *args): - cmd_line = [sys.executable, '-E'] - cmd_line.extend(args) - with open(os.devnull, 'w') as devnull: - return subprocess.call(cmd_line, stdout=devnull, - stderr=subprocess.STDOUT) + return python_exit_code(*args) def test_directories(self): self.assertNotEqual(self.exit_code('.'), 0) @@ -107,10 +104,10 @@ # -m and -i need to play well together # Runs the timeit module and checks the __main__ # namespace has been populated appropriately - p = _spawn_python('-i', '-m', 'timeit', '-n', '1') + p = spawn_python('-i', '-m', 'timeit', '-n', '1') p.stdin.write(b'Timer\n') p.stdin.write(b'exit()\n') - data = _kill_python(p) + data = kill_python(p) self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) @@ -154,7 +151,7 @@ def test_unbuffered_input(self): # sys.stdin still works with '-u' code = ("import sys; sys.stdout.write(sys.stdin.read(1))") - p = _spawn_python('-u', '-c', code) + p = spawn_python('-u', '-c', code) p.stdin.write(b'x') p.stdin.flush() data, rc = _kill_python_and_exit_code(p) @@ -166,7 +163,8 @@ path1 = "ABCDE" * 100 path2 = "FGHIJ" * 100 env['PYTHONPATH'] = path1 + os.pathsep + path2 - p = _spawn_python('-S', '-c', 'import sys; print(sys.path)') + p = _spawn_python_with_env('-S', '-c', + 'import sys; print(sys.path)') stdout, _ = p.communicate() self.assertTrue(path1.encode('ascii') in stdout) self.assertTrue(path2.encode('ascii') in stdout) Modified: python/branches/py3k/Lib/test/test_cmd_line_script.py ============================================================================== --- python/branches/py3k/Lib/test/test_cmd_line_script.py (original) +++ python/branches/py3k/Lib/test/test_cmd_line_script.py Mon Nov 16 07:49:25 2009 @@ -5,35 +5,12 @@ import os.path import sys import test.support -import tempfile -import subprocess -import py_compile -import contextlib -import shutil -import zipfile +from test.script_helper import (spawn_python, kill_python, run_python, + temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) verbose = test.support.verbose -# XXX ncoghlan: Should we consider moving these to support? -from test.test_cmd_line import _spawn_python, _kill_python - -def _run_python(*args): - if __debug__: - p = _spawn_python(*args) - else: - p = _spawn_python('-O', *args) - stdout_data = _kill_python(p) - return p.wait(), stdout_data.decode() - - at contextlib.contextmanager -def temp_dir(): - dirname = tempfile.mkdtemp() - dirname = os.path.realpath(dirname) - try: - yield dirname - finally: - shutil.rmtree(dirname) - test_source = """\ # Script may be run with optimisation enabled, so don't rely on assert # statements being executed @@ -60,63 +37,12 @@ """ def _make_test_script(script_dir, script_basename, source=test_source): - script_filename = script_basename+os.path.extsep+'py' - script_name = os.path.join(script_dir, script_filename) - script_file = open(script_name, 'w') - script_file.write(source) - script_file.close() - return script_name - -def _compile_test_script(script_name): - py_compile.compile(script_name, doraise=True) - if __debug__: - compiled_name = script_name + 'c' - else: - compiled_name = script_name + 'o' - return compiled_name - -def _make_test_zip(zip_dir, zip_basename, script_name, name_in_zip=None): - zip_filename = zip_basename+os.path.extsep+"zip" - zip_name = os.path.join(zip_dir, zip_filename) - zip_file = zipfile.ZipFile(zip_name, 'w') - if name_in_zip is None: - name_in_zip = os.path.basename(script_name) - zip_file.write(script_name, name_in_zip) - zip_file.close() - #if verbose: - # zip_file = zipfile.ZipFile(zip_name, 'r') - # print("Contents of %r:" % zip_name) - # zip_file.printdir() - # zip_file.close() - return zip_name, os.path.join(zip_name, name_in_zip) - -def _make_test_pkg(pkg_dir): - os.mkdir(pkg_dir) - _make_test_script(pkg_dir, '__init__', '') + return make_script(script_dir, script_basename, source) def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, source=test_source, depth=1): - init_name = _make_test_script(zip_dir, '__init__', '') - init_basename = os.path.basename(init_name) - script_name = _make_test_script(zip_dir, script_basename, source) - pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] - script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) - zip_filename = zip_basename+os.extsep+'zip' - zip_name = os.path.join(zip_dir, zip_filename) - zip_file = zipfile.ZipFile(zip_name, 'w') - for name in pkg_names: - init_name_in_zip = os.path.join(name, init_basename) - zip_file.write(init_name, init_name_in_zip) - zip_file.write(script_name, script_name_in_zip) - zip_file.close() - os.unlink(init_name) - os.unlink(script_name) - #if verbose: - # zip_file = zipfile.ZipFile(zip_name, 'r') - # print('Contents of %r:' % zip_name) - # zip_file.printdir() - # zip_file.close() - return zip_name, os.path.join(zip_name, script_name_in_zip) + return make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth) # There's no easy way to pass the script directory in to get # -m to work (avoiding that is the whole point of making @@ -134,14 +60,14 @@ else: path = repr(path) source = launch_source % (path, module_name) - return _make_test_script(script_dir, script_basename, source) + return make_script(script_dir, script_basename, source) class CmdLineTest(unittest.TestCase): def _check_script(self, script_name, expected_file, expected_argv0, expected_package, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) - exit_code, data = _run_python(*run_args) + exit_code, data = run_python(*run_args) if verbose: print("Output from test script %r:" % script_name) print(data) @@ -154,19 +80,19 @@ print(printed_file) print(printed_package) print(printed_argv0) - self.assertTrue(printed_file in data) - self.assertTrue(printed_package in data) - self.assertTrue(printed_argv0 in data) + self.assertTrue(printed_file.encode('utf-8') in data) + self.assertTrue(printed_package.encode('utf-8') in data) + self.assertTrue(printed_argv0.encode('utf-8') in data) def _check_import_error(self, script_name, expected_msg, *cmd_line_switches): run_args = cmd_line_switches + (script_name,) - exit_code, data = _run_python(*run_args) + exit_code, data = run_python(*run_args) if verbose: print('Output from test script %r:' % script_name) print(data) print('Expected output: %r' % expected_msg) - self.assertTrue(expected_msg in data) + self.assertTrue(expected_msg.encode('utf-8') in data) def test_basic_script(self): with temp_dir() as script_dir: @@ -176,7 +102,7 @@ def test_script_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) self._check_script(compiled_name, compiled_name, compiled_name, None) @@ -188,39 +114,39 @@ def test_directory_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) self._check_script(script_dir, compiled_name, script_dir, '') def test_directory_error(self): with temp_dir() as script_dir: - msg = "can't find '__main__.py' in %r" % script_dir + msg = "can't find '__main__' module in %r" % script_dir self._check_import_error(script_dir, msg) def test_zipfile(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', script_name) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) self._check_script(zip_name, run_name, zip_name, '') def test_zipfile_compiled(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') - compiled_name = _compile_test_script(script_name) - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', compiled_name) + compiled_name = compile_script(script_name) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) self._check_script(zip_name, run_name, zip_name, '') def test_zipfile_error(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'not_main') - zip_name, run_name = _make_test_zip(script_dir, 'test_zip', script_name) - msg = "can't find '__main__.py' in %r" % zip_name + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) + msg = "can't find '__main__' module in %r" % zip_name self._check_import_error(zip_name, msg) def test_module_in_package(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, 'script') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script') self._check_script(launch_name, script_name, script_name, 'test_pkg') @@ -240,7 +166,7 @@ def test_package(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name, script_name, @@ -249,9 +175,9 @@ def test_package_compiled(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') - compiled_name = _compile_test_script(script_name) + compiled_name = compile_script(script_name) os.remove(script_name) launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') self._check_script(launch_name, compiled_name, @@ -260,7 +186,7 @@ def test_package_error(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) msg = ("'test_pkg' is a package and cannot " "be directly executed") launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') @@ -269,9 +195,9 @@ def test_package_recursion(self): with temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') - _make_test_pkg(pkg_dir) + make_pkg(pkg_dir) main_dir = os.path.join(pkg_dir, '__main__') - _make_test_pkg(main_dir) + make_pkg(main_dir) msg = ("Cannot use package as __main__ module; " "'test_pkg' is a package and cannot " "be directly executed") Modified: python/branches/py3k/Lib/test/test_runpy.py ============================================================================== --- python/branches/py3k/Lib/test/test_runpy.py (original) +++ python/branches/py3k/Lib/test/test_runpy.py Mon Nov 16 07:49:25 2009 @@ -5,8 +5,11 @@ import sys import tempfile from test.support import verbose, run_unittest, forget -from runpy import _run_code, _run_module_code, run_module +from test.script_helper import (temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) + +from runpy import _run_code, _run_module_code, run_module, run_path # Note: This module can't safely test _run_module_as_main as it # runs its tests in the current process, which would mess with the # real __main__ module (usually test.regrtest) @@ -15,6 +18,7 @@ # Set up the test code and expected results class RunModuleCodeTest(unittest.TestCase): + """Unit tests for runpy._run_code and runpy._run_module_code""" expected_result = ["Top level assignment", "Lower level reference"] test_source = ( @@ -37,14 +41,14 @@ def test_run_code(self): saved_argv0 = sys.argv[0] d = _run_code(self.test_source, {}) - self.assertTrue(d["result"] == self.expected_result) - self.assertTrue(d["__name__"] is None) - self.assertTrue(d["__file__"] is None) - self.assertTrue(d["__loader__"] is None) - self.assertTrue(d["__package__"] is None) - self.assertTrue(d["run_argv0"] is saved_argv0) - self.assertTrue("run_name" not in d) - self.assertTrue(sys.argv[0] is saved_argv0) + self.assertEqual(d["result"], self.expected_result) + self.assertIs(d["__name__"], None) + self.assertIs(d["__file__"], None) + self.assertIs(d["__loader__"], None) + self.assertIs(d["__package__"], None) + self.assertIs(d["run_argv0"], saved_argv0) + self.assertNotIn("run_name", d) + self.assertIs(sys.argv[0], saved_argv0) def test_run_module_code(self): initial = object() @@ -60,22 +64,23 @@ file, loader, package) - self.assertTrue("result" not in d1) - self.assertTrue(d2["initial"] is initial) + self.assertNotIn("result", d1) + self.assertIs(d2["initial"], initial) self.assertEqual(d2["result"], self.expected_result) self.assertEqual(d2["nested"]["x"], 1) - self.assertTrue(d2["__name__"] is name) + self.assertIs(d2["__name__"], name) self.assertTrue(d2["run_name_in_sys_modules"]) self.assertTrue(d2["module_in_sys_modules"]) - self.assertTrue(d2["__file__"] is file) - self.assertTrue(d2["run_argv0"] is file) - self.assertTrue(d2["__loader__"] is loader) - self.assertTrue(d2["__package__"] is package) - self.assertTrue(sys.argv[0] is saved_argv0) - self.assertTrue(name not in sys.modules) + self.assertIs(d2["__file__"], file) + self.assertIs(d2["run_argv0"], file) + self.assertIs(d2["__loader__"], loader) + self.assertIs(d2["__package__"], package) + self.assertIs(sys.argv[0], saved_argv0) + self.assertNotIn(name, sys.modules) class RunModuleTest(unittest.TestCase): + """Unit tests for runpy.run_module""" def expect_import_error(self, mod_name): try: @@ -245,9 +250,126 @@ self._check_relative_imports(depth, "__main__") +class RunPathTest(unittest.TestCase): + """Unit tests for runpy.run_path""" + # Based on corresponding tests in test_cmd_line_script + + test_source = """\ +# Script may be run with optimisation enabled, so don't rely on assert +# statements being executed +def assertEqual(lhs, rhs): + if lhs != rhs: + raise AssertionError('%r != %r' % (lhs, rhs)) +def assertIs(lhs, rhs): + if lhs is not rhs: + raise AssertionError('%r is not %r' % (lhs, rhs)) +# Check basic code execution +result = ['Top level assignment'] +def f(): + result.append('Lower level reference') +f() +assertEqual(result, ['Top level assignment', 'Lower level reference']) +# Check the sys module +import sys +assertIs(globals(), sys.modules[__name__].__dict__) +argv0 = sys.argv[0] +""" + + def _make_test_script(self, script_dir, script_basename, source=None): + if source is None: + source = self.test_source + return make_script(script_dir, script_basename, source) + + def _check_script(self, script_name, expected_name, expected_file, + expected_argv0, expected_package): + result = run_path(script_name) + self.assertEqual(result["__name__"], expected_name) + self.assertEqual(result["__file__"], expected_file) + self.assertIn("argv0", result) + self.assertEqual(result["argv0"], expected_argv0) + self.assertEqual(result["__package__"], expected_package) + + def _check_import_error(self, script_name, msg): + # Double backslashes to handle path separators on Windows + msg = msg.replace("\\", "\\\\") + self.assertRaisesRegexp(ImportError, msg, run_path, script_name) + + def test_basic_script(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name) + self._check_script(script_name, "", script_name, + script_name, None) + + def test_script_compiled(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + os.remove(script_name) + self._check_script(compiled_name, "", compiled_name, + compiled_name, None) + + def test_directory(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + self._check_script(script_dir, "", script_name, + script_dir, '') + + def test_directory_compiled(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + os.remove(script_name) + self._check_script(script_dir, "", compiled_name, + script_dir, '') + + def test_directory_error(self): + with temp_dir() as script_dir: + mod_name = 'not_main' + script_name = self._make_test_script(script_dir, mod_name) + msg = "can't find '__main__' module in %r" % script_dir + self._check_import_error(script_dir, msg) + + def test_zipfile(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + self._check_script(zip_name, "", fname, zip_name, '') + + def test_zipfile_compiled(self): + with temp_dir() as script_dir: + mod_name = '__main__' + script_name = self._make_test_script(script_dir, mod_name) + compiled_name = compile_script(script_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', compiled_name) + self._check_script(zip_name, "", fname, zip_name, '') + + def test_zipfile_error(self): + with temp_dir() as script_dir: + mod_name = 'not_main' + script_name = self._make_test_script(script_dir, mod_name) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + msg = "can't find '__main__' module in %r" % zip_name + self._check_import_error(zip_name, msg) + + def test_main_recursion_error(self): + with temp_dir() as script_dir, temp_dir() as dummy_dir: + mod_name = '__main__' + source = ("import runpy\n" + "runpy.run_path(%r)\n") % dummy_dir + script_name = self._make_test_script(script_dir, mod_name, source) + zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) + msg = "recursion depth exceeded" + self.assertRaisesRegexp(RuntimeError, msg, run_path, zip_name) + + + def test_main(): - run_unittest(RunModuleCodeTest) - run_unittest(RunModuleTest) + run_unittest(RunModuleCodeTest, RunModuleTest, RunPathTest) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Lib/test/test_zipimport_support.py ============================================================================== --- python/branches/py3k/Lib/test/test_zipimport_support.py (original) +++ python/branches/py3k/Lib/test/test_zipimport_support.py Mon Nov 16 07:49:25 2009 @@ -14,6 +14,9 @@ import inspect import linecache import pdb +from test.script_helper import (spawn_python, kill_python, run_python, + temp_dir, make_script, compile_script, + make_pkg, make_zip_script, make_zip_pkg) verbose = test.support.verbose @@ -29,11 +32,6 @@ # Retrieve some helpers from other test cases from test import test_doctest, sample_doctest from test.test_importhooks import ImportHooksBaseTestCase -from test.test_cmd_line_script import temp_dir, _run_python, \ - _spawn_python, _kill_python, \ - _make_test_script, \ - _compile_test_script, \ - _make_test_zip, _make_test_pkg def _run_object_doctest(obj, module): @@ -78,10 +76,10 @@ def test_inspect_getsource_issue4223(self): test_src = "def foo(): pass\n" with temp_dir() as d: - init_name = _make_test_script(d, '__init__', test_src) + init_name = make_script(d, '__init__', test_src) name_in_zip = os.path.join('zip_pkg', os.path.basename(init_name)) - zip_name, run_name = _make_test_zip(d, 'test_zip', + zip_name, run_name = make_zip_script(d, 'test_zip', init_name, name_in_zip) os.remove(init_name) sys.path.insert(0, zip_name) @@ -106,9 +104,9 @@ sample_src = sample_src.replace("test.test_doctest", "test_zipped_doctest") with temp_dir() as d: - script_name = _make_test_script(d, 'test_zipped_doctest', + script_name = make_script(d, 'test_zipped_doctest', test_src) - zip_name, run_name = _make_test_zip(d, 'test_zip', + zip_name, run_name = make_zip_script(d, 'test_zip', script_name) z = zipfile.ZipFile(zip_name, 'a') z.writestr("sample_zipped_doctest.py", sample_src) @@ -180,23 +178,23 @@ """) pattern = 'File "%s", line 2, in %s' with temp_dir() as d: - script_name = _make_test_script(d, 'script', test_src) - exit_code, data = _run_python(script_name) + script_name = make_script(d, 'script', test_src) + exit_code, data = run_python(script_name) expected = pattern % (script_name, "__main__.Test") if verbose: print ("Expected line", expected) print ("Got stdout:") print (data) - self.assertTrue(expected in data) - zip_name, run_name = _make_test_zip(d, "test_zip", + self.assertTrue(expected.encode('utf-8') in data) + zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') - exit_code, data = _run_python(zip_name) + exit_code, data = run_python(zip_name) expected = pattern % (run_name, "__main__.Test") if verbose: print ("Expected line", expected) print ("Got stdout:") print (data) - self.assertTrue(expected in data) + self.assertTrue(expected.encode('utf-8') in data) def test_pdb_issue4201(self): test_src = textwrap.dedent("""\ @@ -207,17 +205,17 @@ pdb.runcall(f) """) with temp_dir() as d: - script_name = _make_test_script(d, 'script', test_src) - p = _spawn_python(script_name) + script_name = make_script(d, 'script', test_src) + p = spawn_python(script_name) p.stdin.write(b'l\n') - data = _kill_python(p).decode() - self.assertTrue(script_name in data) - zip_name, run_name = _make_test_zip(d, "test_zip", + data = kill_python(p) + self.assertTrue(script_name.encode('utf-8') in data) + zip_name, run_name = make_zip_script(d, "test_zip", script_name, '__main__.py') - p = _spawn_python(zip_name) + p = spawn_python(zip_name) p.stdin.write(b'l\n') - data = _kill_python(p).decode() - self.assertTrue(run_name in data) + data = kill_python(p) + self.assertTrue(run_name.encode('utf-8') in data) def test_main(): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 16 07:49:25 2009 @@ -137,6 +137,12 @@ - Issue #4969: The mimetypes module now reads the MIME database from the registry under Windows. Patch by Gabriel Genellina. +- Issue #6816: runpy now provides a run_path function that allows Python code + to execute file paths that refer to source or compiled Python files as well + as zipfiles, directories and other valid sys.path entries that contain a + __main__.py file. This allows applications that run other Python scripts to + support the same flexibility as the CPython command line itself. + - Issue #7318: multiprocessing now uses a timeout when it fails to establish a connection with another process, rather than looping endlessly. The default timeout is 20 seconds, which should be amply sufficient for From python-checkins at python.org Mon Nov 16 07:57:43 2009 From: python-checkins at python.org (nick.coghlan) Date: Mon, 16 Nov 2009 06:57:43 -0000 Subject: [Python-checkins] r76325 - python/branches/release31-maint Message-ID: Author: nick.coghlan Date: Mon Nov 16 07:57:43 2009 New Revision: 76325 Log: Blocked revisions 76324 via svnmerge ................ r76324 | nick.coghlan | 2009-11-16 16:49:25 +1000 (Mon, 16 Nov 2009) | 17 lines Merged revisions 76286-76287,76289-76294,76296-76299,76301-76305,76307,76310-76311,76313-76322 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76286 | nick.coghlan | 2009-11-15 17:30:34 +1000 (Sun, 15 Nov 2009) | 1 line Issue #6816: expose the zipfile and directory execution mechanism to Python code via the runpy module. Also consolidated some script execution functionality in the test harness into a helper module and removed some implementation details from the runpy module documentation. ........ r76321 | nick.coghlan | 2009-11-16 13:55:51 +1000 (Mon, 16 Nov 2009) | 1 line Account for another cache when hunting ref leaks ........ r76322 | nick.coghlan | 2009-11-16 13:57:32 +1000 (Mon, 16 Nov 2009) | 1 line Allow for backslashes in file paths passed to the regex engine ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Nov 16 17:44:05 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 16 Nov 2009 16:44:05 -0000 Subject: [Python-checkins] r76326 - python/trunk/Doc/library/xml.dom.rst Message-ID: Author: georg.brandl Date: Mon Nov 16 17:44:05 2009 New Revision: 76326 Log: #7302: fix link. Modified: python/trunk/Doc/library/xml.dom.rst Modified: python/trunk/Doc/library/xml.dom.rst ============================================================================== --- python/trunk/Doc/library/xml.dom.rst (original) +++ python/trunk/Doc/library/xml.dom.rst Mon Nov 16 17:44:05 2009 @@ -79,7 +79,7 @@ `Document Object Model (DOM) Level 1 Specification `_ The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`. - `Python Language Mapping Specification `_ + `Python Language Mapping Specification `_ This specifies the mapping from OMG IDL to Python. From python-checkins at python.org Mon Nov 16 17:57:52 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 16:57:52 -0000 Subject: [Python-checkins] r76327 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Nov 16 17:57:52 2009 New Revision: 76327 Log: Blocked revisions 76308 via svnmerge ........ r76308 | mark.dickinson | 2009-11-15 16:18:58 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #7228: Add '%lld' and '%llu' support to PyFormat_FromString, PyFormat_FromStringV and PyErr_Format. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 16 18:00:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 17:00:11 -0000 Subject: [Python-checkins] r76328 - in python/branches/py3k: Doc/c-api/exceptions.rst Doc/c-api/unicode.rst Include/pyport.h Misc/NEWS Modules/_testcapimodule.c Objects/unicodeobject.c configure configure.in pyconfig.h.in Message-ID: Author: mark.dickinson Date: Mon Nov 16 18:00:11 2009 New Revision: 76328 Log: Merged revisions 76308 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76308 | mark.dickinson | 2009-11-15 16:18:58 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #7228: Add '%lld' and '%llu' support to PyFormat_FromString, PyFormat_FromStringV and PyErr_Format. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/exceptions.rst python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k/Include/pyport.h python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_testcapimodule.c python/branches/py3k/Objects/unicodeobject.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Doc/c-api/exceptions.rst ============================================================================== --- python/branches/py3k/Doc/c-api/exceptions.rst (original) +++ python/branches/py3k/Doc/c-api/exceptions.rst Mon Nov 16 18:00:11 2009 @@ -155,6 +155,8 @@ .. % The descriptions for %zd and %zu are wrong, but the truth is complicated .. % because not all compilers support the %z width modifier -- we fake it .. % when necessary via interpolating PY_FORMAT_SIZE_T. + .. % Similar comments apply to the %ll width modifier and + .. % PY_FORMAT_LONG_LONG. +-------------------+---------------+--------------------------------+ | Format Characters | Type | Comment | @@ -176,6 +178,12 @@ | :attr:`%lu` | unsigned long | Exactly equivalent to | | | | ``printf("%lu")``. | +-------------------+---------------+--------------------------------+ + | :attr:`%lld` | long long | Exactly equivalent to | + | | | ``printf("%lld")``. | + +-------------------+---------------+--------------------------------+ + | :attr:`%llu` | unsigned | Exactly equivalent to | + | | long long | ``printf("%llu")``. | + +-------------------+---------------+--------------------------------+ | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | | | | ``printf("%zd")``. | +-------------------+---------------+--------------------------------+ @@ -203,6 +211,14 @@ An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. + .. note:: + + The `"%lld"` and `"%llu"` format specifiers are only available + when `HAVE_LONG_LONG` is defined. + + .. versionchanged:: 3.2 + Support for `"%lld"` and `"%llu"` added. + .. cfunction:: void PyErr_SetNone(PyObject *type) Modified: python/branches/py3k/Doc/c-api/unicode.rst ============================================================================== --- python/branches/py3k/Doc/c-api/unicode.rst (original) +++ python/branches/py3k/Doc/c-api/unicode.rst Mon Nov 16 18:00:11 2009 @@ -232,9 +232,12 @@ types and must correspond exactly to the format characters in the *format* string. The following format characters are allowed: + .. % This should be exactly the same as the table in PyErr_Format. .. % The descriptions for %zd and %zu are wrong, but the truth is complicated .. % because not all compilers support the %z width modifier -- we fake it .. % when necessary via interpolating PY_FORMAT_SIZE_T. + .. % Similar comments apply to the %ll width modifier and + .. % PY_FORMAT_LONG_LONG. +-------------------+---------------------+--------------------------------+ | Format Characters | Type | Comment | @@ -256,6 +259,12 @@ | :attr:`%lu` | unsigned long | Exactly equivalent to | | | | ``printf("%lu")``. | +-------------------+---------------------+--------------------------------+ + | :attr:`%lld` | long long | Exactly equivalent to | + | | | ``printf("%lld")``. | + +-------------------+---------------------+--------------------------------+ + | :attr:`%llu` | unsigned long long | Exactly equivalent to | + | | | ``printf("%llu")``. | + +-------------------+---------------------+--------------------------------+ | :attr:`%zd` | Py_ssize_t | Exactly equivalent to | | | | ``printf("%zd")``. | +-------------------+---------------------+--------------------------------+ @@ -301,6 +310,15 @@ An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. + .. note:: + + The `"%lld"` and `"%llu"` format specifiers are only available + when `HAVE_LONG_LONG` is defined. + + .. versionchanged:: 3.2 + Support for `"%lld"` and `"%llu"` added. + + .. cfunction:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Mon Nov 16 18:00:11 2009 @@ -219,6 +219,22 @@ # endif #endif +/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for + * the long long type instead of the size_t type. It's only available + * when HAVE_LONG_LONG is defined. The "high level" Python format + * functions listed above will interpret "lld" or "llu" correctly on + * all platforms. + */ +#ifdef HAVE_LONG_LONG +# ifndef PY_FORMAT_LONG_LONG +# if defined(MS_WIN64) || defined(MS_WINDOWS) +# define PY_FORMAT_LONG_LONG "I64" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG" +# endif +# endif +#endif + /* Py_LOCAL can be used instead of static to get the fastest possible calling * convention for functions that are local to a given module. * Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 16 18:00:11 2009 @@ -110,6 +110,9 @@ C-API ----- +- Issue #Add '%lld' and '%llu' support to PyString_FromFormat(V) + and PyErr_Format, on machines with HAVE_LONG_LONG defined. + - Issue #6151: Made PyDescr_COMMON conform to standard C (like PyObject_HEAD in PEP 3123). The PyDescr_TYPE and PyDescr_NAME macros should be should used for accessing the d_type and d_name members of structures Modified: python/branches/py3k/Modules/_testcapimodule.c ============================================================================== --- python/branches/py3k/Modules/_testcapimodule.c (original) +++ python/branches/py3k/Modules/_testcapimodule.c Mon Nov 16 18:00:11 2009 @@ -1037,6 +1037,12 @@ CHECK_1_FORMAT("%lu", unsigned long); CHECK_1_FORMAT("%zu", size_t); + /* "%lld" and "%llu" support added in Python 2.7. */ +#ifdef HAVE_LONG_LONG + CHECK_1_FORMAT("%llu", unsigned PY_LONG_LONG); + CHECK_1_FORMAT("%lld", PY_LONG_LONG); +#endif + Py_RETURN_NONE; Fail: Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Mon Nov 16 18:00:11 2009 @@ -667,7 +667,8 @@ #undef CONVERT_WCHAR_TO_SURROGATES static void -makefmt(char *fmt, int longflag, int size_tflag, int zeropad, int width, int precision, char c) +makefmt(char *fmt, int longflag, int longlongflag, int size_tflag, + int zeropad, int width, int precision, char c) { *fmt++ = '%'; if (width) { @@ -679,6 +680,19 @@ fmt += sprintf(fmt, ".%d", precision); if (longflag) *fmt++ = 'l'; + else if (longlongflag) { + /* longlongflag should only ever be nonzero on machines with + HAVE_LONG_LONG defined */ +#ifdef HAVE_LONG_LONG + char *f = PY_FORMAT_LONG_LONG; + while (*f) + *fmt++ = *f++; +#else + /* we shouldn't ever get here */ + assert(0); + *fmt++ = 'l'; +#endif + } else if (size_tflag) { char *f = PY_FORMAT_SIZE_T; while (*f) @@ -690,6 +704,16 @@ #define appendstring(string) {for (copy = string;*copy;) *s++ = *copy++;} +/* size of fixed-size buffer for formatting single arguments */ +#define ITEM_BUFFER_LEN 21 +/* maximum number of characters required for output of %ld. 21 characters + allows for 64-bit integers (in decimal) and an optional sign. */ +#define MAX_LONG_CHARS 21 +/* maximum number of characters required for output of %lld. + We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, + plus 1 for the sign. 53/22 is an upper bound for log10(256). */ +#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22) + PyObject * PyUnicode_FromFormatV(const char *format, va_list vargs) { @@ -705,13 +729,13 @@ Py_UNICODE *s; PyObject *string; /* used by sprintf */ - char buffer[21]; + char buffer[ITEM_BUFFER_LEN+1]; /* use abuffer instead of buffer, if we need more space * (which can happen if there's a format specifier with width). */ char *abuffer = NULL; char *realbuffer; Py_ssize_t abuffersize = 0; - char fmt[60]; /* should be enough for %0width.precisionld */ + char fmt[61]; /* should be enough for %0width.precisionlld */ const char *copy; #ifdef VA_LIST_IS_ARRAY @@ -754,6 +778,9 @@ /* step 3: figure out how large a buffer we need */ for (f = format; *f; f++) { if (*f == '%') { +#ifdef HAVE_LONG_LONG + int longlongflag = 0; +#endif const char* p = f; width = 0; while (ISDIGIT((unsigned)*f)) @@ -764,9 +791,21 @@ /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since * they don't affect the amount of space we reserve. */ - if ((*f == 'l' || *f == 'z') && - (f[1] == 'd' || f[1] == 'u')) + if (*f == 'l') { + if (f[1] == 'd' || f[1] == 'u') { + ++f; + } +#ifdef HAVE_LONG_LONG + else if (f[1] == 'l' && + (f[2] == 'd' || f[2] == 'u')) { + longlongflag = 1; + f += 2; + } +#endif + } + else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { ++f; + } switch (*f) { case 'c': @@ -777,14 +816,21 @@ break; case 'd': case 'u': case 'i': case 'x': (void) va_arg(count, int); - /* 20 bytes is enough to hold a 64-bit - integer. Decimal takes the most space. - This isn't enough for octal. - If a width is specified we need more - (which we allocate later). */ - if (width < 20) - width = 20; +#ifdef HAVE_LONG_LONG + if (longlongflag) { + if (width < MAX_LONG_LONG_CHARS) + width = MAX_LONG_LONG_CHARS; + } + else +#endif + /* MAX_LONG_CHARS is enough to hold a 64-bit integer, + including sign. Decimal takes the most space. This + isn't enough for octal. If a width is specified we + need more (which we allocate later). */ + if (width < MAX_LONG_CHARS) + width = MAX_LONG_CHARS; n += width; + /* XXX should allow for large precision here too. */ if (abuffersize < width) abuffersize = width; break; @@ -881,8 +927,9 @@ n++; } expand: - if (abuffersize > 20) { - abuffer = PyObject_Malloc(abuffersize); + if (abuffersize > ITEM_BUFFER_LEN) { + /* add 1 for sprintf's trailing null byte */ + abuffer = PyObject_Malloc(abuffersize + 1); if (!abuffer) { PyErr_NoMemory(); goto fail; @@ -906,6 +953,7 @@ if (*f == '%') { const char* p = f++; int longflag = 0; + int longlongflag = 0; int size_tflag = 0; zeropad = (*f == '0'); /* parse the width.precision part */ @@ -918,11 +966,19 @@ while (ISDIGIT((unsigned)*f)) precision = (precision*10) + *f++ - '0'; } - /* handle the long flag, but only for %ld and %lu. - others can be added when necessary. */ - if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) { - longflag = 1; - ++f; + /* Handle %ld, %lu, %lld and %llu. */ + if (*f == 'l') { + if (f[1] == 'd' || f[1] == 'u') { + longflag = 1; + ++f; + } +#ifdef HAVE_LONG_LONG + else if (f[1] == 'l' && + (f[2] == 'd' || f[2] == 'u')) { + longlongflag = 1; + f += 2; + } +#endif } /* handle the size_t flag. */ if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { @@ -935,9 +991,14 @@ *s++ = va_arg(vargs, int); break; case 'd': - makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'd'); + makefmt(fmt, longflag, longlongflag, size_tflag, zeropad, + width, precision, 'd'); if (longflag) sprintf(realbuffer, fmt, va_arg(vargs, long)); +#ifdef HAVE_LONG_LONG + else if (longlongflag) + sprintf(realbuffer, fmt, va_arg(vargs, PY_LONG_LONG)); +#endif else if (size_tflag) sprintf(realbuffer, fmt, va_arg(vargs, Py_ssize_t)); else @@ -945,9 +1006,15 @@ appendstring(realbuffer); break; case 'u': - makefmt(fmt, longflag, size_tflag, zeropad, width, precision, 'u'); + makefmt(fmt, longflag, longlongflag, size_tflag, zeropad, + width, precision, 'u'); if (longflag) sprintf(realbuffer, fmt, va_arg(vargs, unsigned long)); +#ifdef HAVE_LONG_LONG + else if (longlongflag) + sprintf(realbuffer, fmt, va_arg(vargs, + unsigned PY_LONG_LONG)); +#endif else if (size_tflag) sprintf(realbuffer, fmt, va_arg(vargs, size_t)); else @@ -955,12 +1022,12 @@ appendstring(realbuffer); break; case 'i': - makefmt(fmt, 0, 0, zeropad, width, precision, 'i'); + makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'i'); sprintf(realbuffer, fmt, va_arg(vargs, int)); appendstring(realbuffer); break; case 'x': - makefmt(fmt, 0, 0, zeropad, width, precision, 'x'); + makefmt(fmt, 0, 0, 0, zeropad, width, precision, 'x'); sprintf(realbuffer, fmt, va_arg(vargs, int)); appendstring(realbuffer); break; Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Mon Nov 16 18:00:11 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76030 . +# From configure.in Revision: 76301 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -26314,6 +26314,104 @@ echo "${ECHO_T}no" >&6; } fi +if test "$have_long_long" = yes +then + { echo "$as_me:$LINENO: checking for %lld and %llu printf() format support" >&5 +echo $ECHO_N "checking for %lld and %llu printf() format support... $ECHO_C" >&6; } + if test "${ac_cv_have_long_long_format+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_have_long_long_format=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + #include + #include + + #ifdef HAVE_SYS_TYPES_H + #include + #endif + + int main() + { + char buffer[256]; + + if (sprintf(buffer, "%lld", (long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + if (sprintf(buffer, "%lld", (long long)-123) < 0) + return 1; + if (strcmp(buffer, "-123")) + return 1; + + if (sprintf(buffer, "%llu", (unsigned long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + return 0; + } + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_have_long_long_format=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_have_long_long_format=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + + { echo "$as_me:$LINENO: result: $ac_cv_have_long_long_format" >&5 +echo "${ECHO_T}$ac_cv_have_long_long_format" >&6; } +fi + +if test $ac_cv_have_long_long_format = yes +then + +cat >>confdefs.h <<\_ACEOF +#define PY_FORMAT_LONG_LONG "ll" +_ACEOF + +fi + + { echo "$as_me:$LINENO: checking for %zd printf() format support" >&5 echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6; } if test "${ac_cv_have_size_t_format+set}" = set; then Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Mon Nov 16 18:00:11 2009 @@ -3806,6 +3806,54 @@ AC_MSG_RESULT(no) fi +if test "$have_long_long" = yes +then + AC_MSG_CHECKING(for %lld and %llu printf() format support) + AC_CACHE_VAL(ac_cv_have_long_long_format, + AC_TRY_RUN([[ + #include + #include + #include + + #ifdef HAVE_SYS_TYPES_H + #include + #endif + + int main() + { + char buffer[256]; + + if (sprintf(buffer, "%lld", (long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + if (sprintf(buffer, "%lld", (long long)-123) < 0) + return 1; + if (strcmp(buffer, "-123")) + return 1; + + if (sprintf(buffer, "%llu", (unsigned long long)123) < 0) + return 1; + if (strcmp(buffer, "123")) + return 1; + + return 0; + } + ]], ac_cv_have_long_long_format=yes, + ac_cv_have_long_long_format=no, + ac_cv_have_long_long_format=no) + ) + AC_MSG_RESULT($ac_cv_have_long_long_format) +fi + +if test $ac_cv_have_long_long_format = yes +then + AC_DEFINE(PY_FORMAT_LONG_LONG, "ll", + [Define to printf format modifier for long long type]) +fi + + AC_MSG_CHECKING(for %zd printf() format support) AC_CACHE_VAL(ac_cv_have_size_t_format, AC_TRY_RUN([[ Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Mon Nov 16 18:00:11 2009 @@ -910,6 +910,9 @@ /* Define as the preferred size in bits of long digits */ #undef PYLONG_BITS_IN_DIGIT +/* Define to printf format modifier for long long type */ +#undef PY_FORMAT_LONG_LONG + /* Define to printf format modifier for Py_ssize_t */ #undef PY_FORMAT_SIZE_T From python-checkins at python.org Mon Nov 16 18:01:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 17:01:23 -0000 Subject: [Python-checkins] r76329 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Mon Nov 16 18:01:22 2009 New Revision: 76329 Log: Blocked revisions 76328 via svnmerge ................ r76328 | mark.dickinson | 2009-11-16 17:00:11 +0000 (Mon, 16 Nov 2009) | 10 lines Merged revisions 76308 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76308 | mark.dickinson | 2009-11-15 16:18:58 +0000 (Sun, 15 Nov 2009) | 3 lines Issue #7228: Add '%lld' and '%llu' support to PyFormat_FromString, PyFormat_FromStringV and PyErr_Format. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Nov 16 18:33:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 17:33:25 -0000 Subject: [Python-checkins] r76330 - python/trunk/Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Mon Nov 16 18:33:25 2009 New Revision: 76330 Log: Silence MSVC warning about unary minus applied to unsigned type. Modified: python/trunk/Objects/rangeobject.c Modified: python/trunk/Objects/rangeobject.c ============================================================================== --- python/trunk/Objects/rangeobject.c (original) +++ python/trunk/Objects/rangeobject.c Mon Nov 16 18:33:25 2009 @@ -316,7 +316,7 @@ calculation is also done modulo ULONG_MAX+1. */ it->start = (long)(start + (unsigned long)(len-1) * step); - it->step = (long)(-(unsigned long)step); + it->step = (long)(0UL-step); return (PyObject *)it; } From python-checkins at python.org Mon Nov 16 18:34:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 17:34:13 -0000 Subject: [Python-checkins] r76331 - in python/branches/release26-maint: Objects/rangeobject.c Message-ID: Author: mark.dickinson Date: Mon Nov 16 18:34:11 2009 New Revision: 76331 Log: Merged revisions 76330 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76330 | mark.dickinson | 2009-11-16 17:33:25 +0000 (Mon, 16 Nov 2009) | 1 line Silence MSVC warning about unary minus applied to unsigned type. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Objects/rangeobject.c Modified: python/branches/release26-maint/Objects/rangeobject.c ============================================================================== --- python/branches/release26-maint/Objects/rangeobject.c (original) +++ python/branches/release26-maint/Objects/rangeobject.c Mon Nov 16 18:34:11 2009 @@ -316,7 +316,7 @@ calculation is also done modulo ULONG_MAX+1. */ it->start = (long)(start + (unsigned long)(len-1) * step); - it->step = (long)(-(unsigned long)step); + it->step = (long)(0UL-step); return (PyObject *)it; } From python-checkins at python.org Mon Nov 16 18:36:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 17:36:10 -0000 Subject: [Python-checkins] r76332 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Nov 16 18:36:10 2009 New Revision: 76332 Log: Blocked revisions 76330 via svnmerge ........ r76330 | mark.dickinson | 2009-11-16 17:33:25 +0000 (Mon, 16 Nov 2009) | 1 line Silence MSVC warning about unary minus applied to unsigned type. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Nov 16 20:17:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 19:17:16 -0000 Subject: [Python-checkins] r76333 - python/trunk/Objects/intobject.c Message-ID: Author: mark.dickinson Date: Mon Nov 16 20:17:16 2009 New Revision: 76333 Log: Silence another MSVC warning about unary minus. Modified: python/trunk/Objects/intobject.c Modified: python/trunk/Objects/intobject.c ============================================================================== --- python/trunk/Objects/intobject.c (original) +++ python/trunk/Objects/intobject.c Mon Nov 16 20:17:16 2009 @@ -1117,7 +1117,7 @@ long n = v->ob_ival; unsigned long absn; p = bufend = buf + sizeof(buf); - absn = n < 0 ? -(unsigned long)n : n; + absn = n < 0 ? 0UL - n : n; do { *--p = '0' + absn % 10; absn /= 10; From python-checkins at python.org Mon Nov 16 20:17:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 19:17:55 -0000 Subject: [Python-checkins] r76334 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Nov 16 20:17:54 2009 New Revision: 76334 Log: Blocked revisions 76333 via svnmerge ........ r76333 | mark.dickinson | 2009-11-16 19:17:16 +0000 (Mon, 16 Nov 2009) | 1 line Silence another MSVC warning about unary minus. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 16 20:18:32 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 16 Nov 2009 19:18:32 -0000 Subject: [Python-checkins] r76335 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Nov 16 20:18:32 2009 New Revision: 76335 Log: Blocked revisions 76333 via svnmerge ........ r76333 | mark.dickinson | 2009-11-16 19:17:16 +0000 (Mon, 16 Nov 2009) | 1 line Silence another MSVC warning about unary minus. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 17 00:07:52 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 16 Nov 2009 23:07:52 -0000 Subject: [Python-checkins] r76336 - peps/trunk/pep-0373.txt Message-ID: Author: benjamin.peterson Date: Tue Nov 17 00:07:52 2009 New Revision: 76336 Log: 2.7 only now Modified: peps/trunk/pep-0373.txt Modified: peps/trunk/pep-0373.txt ============================================================================== --- peps/trunk/pep-0373.txt (original) +++ peps/trunk/pep-0373.txt Tue Nov 17 00:07:52 2009 @@ -1,5 +1,5 @@ PEP: 373 -Title: Python 2.7 and 3.2 Release Schedule +Title: Python 2.7 Release Schedule Version: $Revision$ Last-Modified: $Date$ Author: Benjamin Peterson @@ -25,7 +25,7 @@ ============================ ================== Position Name ============================ ================== -2.7 and 3.2 Release Manager Benjamin Peterson +2.7 Release Manager Benjamin Peterson Windows installers Martin v. Loewis Mac installers Ronald Oussoren ============================ ================== @@ -34,21 +34,17 @@ Release Schedule ================ -2.7 and 3.2 will be released at the same time (or at least have feature freeze -at the same time) in order to keep the 2.x branch from having features that the -3.x one does not. - The current schedule is: -- 2.7/3.2 alpha 1 2009-12-05 -- 2.7/3.2 alpha 2 2010-01-09 -- 2.7/3.2 alpha 3 2010-02-06 -- 2.7/3.2 alpha 4 2010-03-06 -- 2.7/3.2 beta 1 2010-04-03 -- 2.7/3.2 beta 2 2010-05-01 -- 2.7/3.2 rc1 2010-05-29 -- 2.7/3.2 rc2 2010-06-12 -- 2.7/3.2 final 2010-06-26 +- 2.7 alpha 1 2009-12-05 +- 2.7 alpha 2 2010-01-09 +- 2.7 alpha 3 2010-02-06 +- 2.7 alpha 4 2010-03-06 +- 2.7 beta 1 2010-04-03 +- 2.7 beta 2 2010-05-01 +- 2.7 rc1 2010-05-29 +- 2.7 rc2 2010-06-12 +- 2.7 final 2010-06-26 Possible features for 2.7 From solipsis at pitrou.net Tue Nov 17 00:46:31 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 17 Nov 2009 00:46:31 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76328): sum=41 Message-ID: <20091116234631.EDEAB1780F@ns6635.ovh.net> py3k results for svn r76328 (hg cset 5ae691974c3f) -------------------------------------------------- test_urllib leaked [6, 4, 2] references, sum=12 test_zipimport_support leaked [29, 0, 0] references, sum=29 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogFFaV--', '-x', 'test_httpservers'] From python-checkins at python.org Tue Nov 17 03:42:26 2009 From: python-checkins at python.org (philip.jenvey) Date: Tue, 17 Nov 2009 02:42:26 -0000 Subject: [Python-checkins] r76337 - in python/trunk: Lib/encodings/aliases.py Misc/NEWS Message-ID: Author: philip.jenvey Date: Tue Nov 17 03:42:26 2009 New Revision: 76337 Log: #1757126: fix typo with the cyrillic_asian alias Modified: python/trunk/Lib/encodings/aliases.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/encodings/aliases.py ============================================================================== --- python/trunk/Lib/encodings/aliases.py (original) +++ python/trunk/Lib/encodings/aliases.py Tue Nov 17 03:42:26 2009 @@ -442,7 +442,7 @@ 'csptcp154' : 'ptcp154', 'pt154' : 'ptcp154', 'cp154' : 'ptcp154', - 'cyrillic-asian' : 'ptcp154', + 'cyrillic_asian' : 'ptcp154', # quopri_codec codec 'quopri' : 'quopri_codec', Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Nov 17 03:42:26 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1757126: Fix the cyrillic-asian alias for the ptcp154 encoding. + - Fix several issues with compile(). The input can now contain Windows and Mac newlines and is no longer required to end in a newline. From python-checkins at python.org Tue Nov 17 04:43:15 2009 From: python-checkins at python.org (philip.jenvey) Date: Tue, 17 Nov 2009 03:43:15 -0000 Subject: [Python-checkins] r76338 - in python/branches/py3k: Lib/encodings/aliases.py Misc/NEWS Message-ID: Author: philip.jenvey Date: Tue Nov 17 04:43:14 2009 New Revision: 76338 Log: Merged revisions 76337 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76337 | philip.jenvey | 2009-11-16 18:42:26 -0800 (Mon, 16 Nov 2009) | 2 lines #1757126: fix typo with the cyrillic_asian alias ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/encodings/aliases.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/encodings/aliases.py ============================================================================== --- python/branches/py3k/Lib/encodings/aliases.py (original) +++ python/branches/py3k/Lib/encodings/aliases.py Tue Nov 17 04:43:14 2009 @@ -442,7 +442,7 @@ 'csptcp154' : 'ptcp154', 'pt154' : 'ptcp154', 'cp154' : 'ptcp154', - 'cyrillic-asian' : 'ptcp154', + 'cyrillic_asian' : 'ptcp154', ## quopri_codec codec #'quopri' : 'quopri_codec', Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Nov 17 04:43:14 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1757126: Fix the cyrillic-asian alias for the ptcp154 encoding. + - Issue #6970: Remove redundant calls when comparing objects that don't implement the relevant rich comparison methods. From python-checkins at python.org Tue Nov 17 21:21:15 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 17 Nov 2009 20:21:15 -0000 Subject: [Python-checkins] r76341 - in python/branches/py3k: Doc/library/ftplib.rst Lib/ftplib.py Lib/test/test_ftplib.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Tue Nov 17 21:21:14 2009 New Revision: 76341 Log: Merged revisions 76309 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76309 | antoine.pitrou | 2009-11-15 18:22:09 +0100 (dim., 15 nov. 2009) | 4 lines Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using TLS or SSL. Patch by Giampaolo Rodola'. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/ftplib.rst python/branches/py3k/Lib/ftplib.py python/branches/py3k/Lib/test/test_ftplib.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/ftplib.rst ============================================================================== --- python/branches/py3k/Doc/library/ftplib.rst (original) +++ python/branches/py3k/Doc/library/ftplib.rst Tue Nov 17 21:21:14 2009 @@ -46,6 +46,42 @@ connection attempt (if is not specified, the global default timeout setting will be used). +.. class:: FTP_TLS(host='', user='', passwd='', acct='', [keyfile[, certfile[, timeout]]]) + + A :class:`FTP` subclass which adds TLS support to FTP as described in + :rfc:`4217`. + Connect as usual to port 21 implicitly securing the FTP control connection + before authenticating. Securing the data connection requires user to + explicitly ask for it by calling :exc:`prot_p()` method. + *keyfile* and *certfile* are optional - they can contain a PEM formatted + private key and certificate chain file for the SSL connection. + + .. versionadded:: 3.2 Contributed by Giampaolo Rodola' + + + Here's a sample session using :class:`FTP_TLS` class: + + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonimously previously securing control channel + >>> ftps.prot_p() # switch to secure data connection + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + >>> + + + .. attribute:: all_errors The set of all exceptions (as a tuple) that methods of :class:`FTP` @@ -312,3 +348,26 @@ :meth:`close` or :meth:`quit` you cannot reopen the connection by issuing another :meth:`login` method). + +FTP_TLS Objects +--------------- + +:class:`FTP_TLS` class inherits from :class:`FTP`, defining these additional objects: + +.. attribute:: FTP_TLS.ssl_version + + The SSL version to use (defaults to *TLSv1*). + +.. method:: FTP_TLS.auth() + + Set up secure control connection by using TLS or SSL, depending on what specified in :meth:`ssl_version` attribute. + +.. method:: FTP_TLS.prot_p() + + Set up secure data connection. + +.. method:: FTP_TLS.prot_c() + + Set up clear text data connection. + + Modified: python/branches/py3k/Lib/ftplib.py ============================================================================== --- python/branches/py3k/Lib/ftplib.py (original) +++ python/branches/py3k/Lib/ftplib.py Tue Nov 17 21:21:14 2009 @@ -33,6 +33,7 @@ # Modified by Jack to work on the mac. # Modified by Siebren to support docstrings and PASV. # Modified by Phil Schwartz to add storbinary and storlines callbacks. +# Modified by Giampaolo Rodola' to add TLS support. # import os @@ -577,6 +578,181 @@ self.file = self.sock = None +try: + import ssl +except ImportError: + pass +else: + class FTP_TLS(FTP): + '''A FTP subclass which adds TLS support to FTP as described + in RFC-4217. + + Connect as usual to port 21 implicitly securing the FTP control + connection before authenticating. + + Securing the data connection requires user to explicitly ask + for it by calling prot_p() method. + + Usage example: + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonimously previously securing control channel + '230 Guest login ok, access restrictions apply.' + >>> ftps.prot_p() # switch to secure data connection + '200 Protection level set to P' + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + '221 Goodbye.' + >>> + ''' + ssl_version = ssl.PROTOCOL_TLSv1 + + def __init__(self, host='', user='', passwd='', acct='', keyfile=None, + certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + self.keyfile = keyfile + self.certfile = certfile + self._prot_p = False + FTP.__init__(self, host, user, passwd, acct, timeout) + + def login(self, user='', passwd='', acct='', secure=True): + if secure and not isinstance(self.sock, ssl.SSLSocket): + self.auth() + return FTP.login(self, user, passwd, acct) + + def auth(self): + '''Set up secure control connection by using TLS/SSL.''' + if isinstance(self.sock, ssl.SSLSocket): + raise ValueError("Already using TLS") + if self.ssl_version == ssl.PROTOCOL_TLSv1: + resp = self.voidcmd('AUTH TLS') + else: + resp = self.voidcmd('AUTH SSL') + self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + self.file = self.sock.makefile(mode='r', encoding=self.encoding) + return resp + + def prot_p(self): + '''Set up secure data connection.''' + # PROT defines whether or not the data channel is to be protected. + # Though RFC-2228 defines four possible protection levels, + # RFC-4217 only recommends two, Clear and Private. + # Clear (PROT C) means that no security is to be used on the + # data-channel, Private (PROT P) means that the data-channel + # should be protected by TLS. + # PBSZ command MUST still be issued, but must have a parameter of + # '0' to indicate that no buffering is taking place and the data + # connection should not be encapsulated. + self.voidcmd('PBSZ 0') + resp = self.voidcmd('PROT P') + self._prot_p = True + return resp + + def prot_c(self): + '''Set up clear text data connection.''' + resp = self.voidcmd('PROT C') + self._prot_p = False + return resp + + # --- Overridden FTP methods + + def ntransfercmd(self, cmd, rest=None): + conn, size = FTP.ntransfercmd(self, cmd, rest) + if self._prot_p: + conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + return conn, size + + def retrbinary(self, cmd, callback, blocksize=8192, rest=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + try: + while 1: + data = conn.recv(blocksize) + if not data: + break + callback(data) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def retrlines(self, cmd, callback = None): + if callback is None: callback = print_line + resp = self.sendcmd('TYPE A') + conn = self.transfercmd(cmd) + fp = conn.makefile('r', encoding=self.encoding) + try: + while 1: + line = fp.readline() + if self.debugging > 2: print('*retr*', repr(line)) + if not line: + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] == '\n': + line = line[:-1] + callback(line) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + fp.close() + conn.close() + return self.voidresp() + + def storbinary(self, cmd, fp, blocksize=8192, callback=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.read(blocksize) + if not buf: break + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def storlines(self, cmd, fp, callback=None): + self.voidcmd('TYPE A') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.readline() + if not buf: break + if buf[-2:] != B_CRLF: + if buf[-1] in B_CRLF: buf = buf[:-1] + buf = buf + B_CRLF + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + __all__.append('FTP_TLS') + all_errors = (Error, IOError, EOFError, ssl.SSLError) + + _150_re = None def parse150(resp): Modified: python/branches/py3k/Lib/test/test_ftplib.py ============================================================================== --- python/branches/py3k/Lib/test/test_ftplib.py (original) +++ python/branches/py3k/Lib/test/test_ftplib.py Tue Nov 17 21:21:14 2009 @@ -1,6 +1,7 @@ """Test script for ftplib module.""" -# Modified by Giampaolo Rodola' to test FTP class and IPv6 environment +# Modified by Giampaolo Rodola' to test FTP class, IPv6 and TLS +# environment import ftplib import threading @@ -8,6 +9,12 @@ import asynchat import socket import io +import errno +import os +try: + import ssl +except ImportError: + ssl = None from unittest import TestCase from test import support @@ -40,6 +47,8 @@ class DummyFTPHandler(asynchat.async_chat): + dtp_handler = DummyDTPHandler + def __init__(self, conn): asynchat.async_chat.__init__(self, conn) self.set_terminator(b"\r\n") @@ -83,7 +92,7 @@ ip = '%d.%d.%d.%d' %tuple(addr[:4]) port = (addr[4] * 256) + addr[5] s = socket.create_connection((ip, port), timeout=2) - self.dtp = DummyDTPHandler(s, baseclass=self) + self.dtp = self.dtp_handler(s, baseclass=self) self.push('200 active data connection established') def cmd_pasv(self, arg): @@ -95,13 +104,13 @@ ip = ip.replace('.', ','); p1 = port / 256; p2 = port % 256 self.push('227 entering passive mode (%s,%d,%d)' %(ip, p1, p2)) conn, addr = sock.accept() - self.dtp = DummyDTPHandler(conn, baseclass=self) + self.dtp = self.dtp_handler(conn, baseclass=self) def cmd_eprt(self, arg): af, ip, port = arg.split(arg[0])[1:-1] port = int(port) s = socket.create_connection((ip, port), timeout=2) - self.dtp = DummyDTPHandler(s, baseclass=self) + self.dtp = self.dtp_handler(s, baseclass=self) self.push('200 active data connection established') def cmd_epsv(self, arg): @@ -112,7 +121,7 @@ port = sock.getsockname()[1] self.push('229 entering extended passive mode (|||%d|)' %port) conn, addr = sock.accept() - self.dtp = DummyDTPHandler(conn, baseclass=self) + self.dtp = self.dtp_handler(conn, baseclass=self) def cmd_echo(self, arg): # sends back the received string (used by the test suite) @@ -227,6 +236,128 @@ raise +if ssl is not None: + + CERTFILE = os.path.join(os.path.dirname(__file__), "keycert.pem") + + class SSLConnection(asyncore.dispatcher): + """An asyncore.dispatcher subclass supporting TLS/SSL.""" + + _ssl_accepting = False + + def secure_connection(self): + self.del_channel() + socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False, + certfile=CERTFILE, server_side=True, + do_handshake_on_connect=False, + ssl_version=ssl.PROTOCOL_SSLv23) + self.set_socket(socket) + self._ssl_accepting = True + + def _do_ssl_handshake(self): + try: + self.socket.do_handshake() + except ssl.SSLError as err: + if err.args[0] in (ssl.SSL_ERROR_WANT_READ, + ssl.SSL_ERROR_WANT_WRITE): + return + elif err.args[0] == ssl.SSL_ERROR_EOF: + return self.handle_close() + raise + except socket.error as err: + if err.args[0] == errno.ECONNABORTED: + return self.handle_close() + else: + self._ssl_accepting = False + + def handle_read_event(self): + if self._ssl_accepting: + self._do_ssl_handshake() + else: + super(SSLConnection, self).handle_read_event() + + def handle_write_event(self): + if self._ssl_accepting: + self._do_ssl_handshake() + else: + super(SSLConnection, self).handle_write_event() + + def send(self, data): + try: + return super(SSLConnection, self).send(data) + except ssl.SSLError as err: + if err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): + return 0 + raise + + def recv(self, buffer_size): + try: + return super(SSLConnection, self).recv(buffer_size) + except ssl.SSLError as err: + if err.args[0] in (ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_ZERO_RETURN): + self.handle_close() + return b'' + raise + + def handle_error(self): + raise + + def close(self): + try: + if isinstance(self.socket, ssl.SSLSocket): + if self.socket._sslobj is not None: + self.socket.unwrap() + finally: + super(SSLConnection, self).close() + + + class DummyTLS_DTPHandler(SSLConnection, DummyDTPHandler): + """A DummyDTPHandler subclass supporting TLS/SSL.""" + + def __init__(self, conn, baseclass): + DummyDTPHandler.__init__(self, conn, baseclass) + if self.baseclass.secure_data_channel: + self.secure_connection() + + + class DummyTLS_FTPHandler(SSLConnection, DummyFTPHandler): + """A DummyFTPHandler subclass supporting TLS/SSL.""" + + dtp_handler = DummyTLS_DTPHandler + + def __init__(self, conn): + DummyFTPHandler.__init__(self, conn) + self.secure_data_channel = False + + def cmd_auth(self, line): + """Set up secure control channel.""" + self.push('234 AUTH TLS successful') + self.secure_connection() + + def cmd_pbsz(self, line): + """Negotiate size of buffer for secure data transfer. + For TLS/SSL the only valid value for the parameter is '0'. + Any other value is accepted but ignored. + """ + self.push('200 PBSZ=0 successful.') + + def cmd_prot(self, line): + """Setup un/secure data channel.""" + arg = line.upper() + if arg == 'C': + self.push('200 Protection set to Clear') + self.secure_data_channel = False + elif arg == 'P': + self.push('200 Protection set to Private') + self.secure_data_channel = True + else: + self.push("502 Unrecognized PROT type (use C or P).") + + + class DummyTLS_FTPServer(DummyFTPServer): + handler = DummyTLS_FTPHandler + + class TestFTPClass(TestCase): def setUp(self): @@ -404,6 +535,81 @@ retr() +class TestTLS_FTPClassMixin(TestFTPClass): + """Repeat TestFTPClass tests starting the TLS layer for both control + and data connections first. + """ + + def setUp(self): + self.server = DummyTLS_FTPServer((HOST, 0)) + self.server.start() + self.client = ftplib.FTP_TLS(timeout=2) + self.client.connect(self.server.host, self.server.port) + # enable TLS + self.client.auth() + self.client.prot_p() + + +class TestTLS_FTPClass(TestCase): + """Specific TLS_FTP class tests.""" + + def setUp(self): + self.server = DummyTLS_FTPServer((HOST, 0)) + self.server.start() + self.client = ftplib.FTP_TLS(timeout=2) + self.client.connect(self.server.host, self.server.port) + + def tearDown(self): + self.client.close() + self.server.stop() + + def test_control_connection(self): + self.assertFalse(isinstance(self.client.sock, ssl.SSLSocket)) + self.client.auth() + self.assertTrue(isinstance(self.client.sock, ssl.SSLSocket)) + + def test_data_connection(self): + # clear text + sock = self.client.transfercmd('list') + self.assertFalse(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + # secured, after PROT P + self.client.prot_p() + sock = self.client.transfercmd('list') + self.assertTrue(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + # PROT C is issued, the connection must be in cleartext again + self.client.prot_c() + sock = self.client.transfercmd('list') + self.assertFalse(isinstance(sock, ssl.SSLSocket)) + sock.close() + self.client.voidresp() + + def test_login(self): + # login() is supposed to implicitly secure the control connection + self.assertFalse(isinstance(self.client.sock, ssl.SSLSocket)) + self.client.login() + self.assertTrue(isinstance(self.client.sock, ssl.SSLSocket)) + # make sure that AUTH TLS doesn't get issued again + self.client.login() + + def test_auth_issued_twice(self): + self.client.auth() + self.assertRaises(ValueError, self.client.auth) + + def test_auth_ssl(self): + try: + self.client.ssl_version = ssl.PROTOCOL_SSLv3 + self.client.auth() + self.assertRaises(ValueError, self.client.auth) + finally: + self.client.ssl_version = ssl.PROTOCOL_TLSv1 + + class TestTimeouts(TestCase): def setUp(self): @@ -505,6 +711,10 @@ pass else: tests.append(TestIPv6Environment) + + if ssl is not None: + tests.extend([TestTLS_FTPClassMixin, TestTLS_FTPClass]) + thread_info = support.threading_setup() try: support.run_unittest(*tests) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Nov 17 21:21:14 2009 @@ -137,6 +137,9 @@ Library ------- +- Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using + TLS or SSL. Patch by Giampaolo Rodola'. + - Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch - Issue #4969: The mimetypes module now reads the MIME database from From python-checkins at python.org Tue Nov 17 22:24:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 17 Nov 2009 21:24:54 -0000 Subject: [Python-checkins] r76350 - python/trunk/Python/bltinmodule.c Message-ID: Author: benjamin.peterson Date: Tue Nov 17 22:24:54 2009 New Revision: 76350 Log: a better callable replacement Modified: python/trunk/Python/bltinmodule.c Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Tue Nov 17 22:24:54 2009 @@ -224,7 +224,7 @@ builtin_callable(PyObject *self, PyObject *v) { if (PyErr_WarnPy3k("callable() not supported in 3.x; " - "use hasattr(o, '__call__')", 1) < 0) + "use isinstance(x, collections.Callable)", 1) < 0) return NULL; return PyBool_FromLong((long)PyCallable_Check(v)); } From python-checkins at python.org Tue Nov 17 22:27:44 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 17 Nov 2009 21:27:44 -0000 Subject: [Python-checkins] r76351 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Tue Nov 17 22:27:44 2009 New Revision: 76351 Log: Blocked revisions 76350 via svnmerge ........ r76350 | benjamin.peterson | 2009-11-17 15:24:54 -0600 (Tue, 17 Nov 2009) | 1 line a better callable replacement ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 17 22:33:08 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 17 Nov 2009 21:33:08 -0000 Subject: [Python-checkins] r76353 - in python/branches/release26-maint: Python/bltinmodule.c Message-ID: Author: benjamin.peterson Date: Tue Nov 17 22:33:08 2009 New Revision: 76353 Log: Merged revisions 76350 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76350 | benjamin.peterson | 2009-11-17 15:24:54 -0600 (Tue, 17 Nov 2009) | 1 line a better callable replacement ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Python/bltinmodule.c Modified: python/branches/release26-maint/Python/bltinmodule.c ============================================================================== --- python/branches/release26-maint/Python/bltinmodule.c (original) +++ python/branches/release26-maint/Python/bltinmodule.c Tue Nov 17 22:33:08 2009 @@ -224,7 +224,7 @@ builtin_callable(PyObject *self, PyObject *v) { if (PyErr_WarnPy3k("callable() not supported in 3.x; " - "use hasattr(o, '__call__')", 1) < 0) + "use isinstance(x, collections.Callable)", 1) < 0) return NULL; return PyBool_FromLong((long)PyCallable_Check(v)); } From python-checkins at python.org Tue Nov 17 23:52:13 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 17 Nov 2009 22:52:13 -0000 Subject: [Python-checkins] r76355 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Tue Nov 17 23:52:13 2009 New Revision: 76355 Log: == is the default operator Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Tue Nov 17 23:52:13 2009 @@ -295,6 +295,8 @@ version numbers, separated by commas. Conditional operators must be one of "<", ">", "<=", ">=", "==", and "!=". Version numbers must be in the format specified in `PEP 386`_. + If no operator is provided with a version, the "==" operator + is used by default. Any number of conditional operators can be specified, e.g. the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. @@ -359,7 +361,8 @@ guaranteed to be compatible with. The format of the field is a series of conditional operators and version numbers, separated by commas. Conditional operators must be one of "<", ">", "<=", - ">=", "==", and "!=". + ">=", "==", and "!=". If no operator is provided with a version, + the "==" operator is used by default. Version numbers must be in the format specified in `PEP 386`_. @@ -370,7 +373,7 @@ Requires-Python: >2.1 Requires-Python: >=2.3.4 - + Requires-Python: 2.5, 2.6 Requires-External (multiple use) Each entry contains a string describing some dependency in the From python-checkins at python.org Tue Nov 17 23:53:57 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 17 Nov 2009 22:53:57 -0000 Subject: [Python-checkins] r76356 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Tue Nov 17 23:53:57 2009 New Revision: 76356 Log: added the full version string for python Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Tue Nov 17 23:53:57 2009 @@ -485,6 +485,7 @@ where ``EXPR`` belongs to any of those: - python_version = '%s.%s' % (sys.version_info[0], sys.version_info[1]) +- python_full_version = sys.version.split()[0] - os.name = os.name - sys.platform = sys.platform - platform.version = platform.version() From python-checkins at python.org Tue Nov 17 23:58:35 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 17 Nov 2009 22:58:35 -0000 Subject: [Python-checkins] r76357 - peps/trunk/pep-0345.txt Message-ID: Author: tarek.ziade Date: Tue Nov 17 23:58:35 2009 New Revision: 76357 Log: removed the external references section Modified: peps/trunk/pep-0345.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Tue Nov 17 23:58:35 2009 @@ -387,22 +387,18 @@ A version declaration is a series of conditional operators and version numbers, separated by commas. Conditional operators - must be one of "<", ">", "<=", ">=", "==", and "!=". Because they - refer to non-Python software releases, version numbers for - this field are **not** required to conform to the format + must be one of "<", ">", "<=", ">=", "==", and "!=". If no + operator is provided with a version, the "==" operator is used by default. + + Because they refer to non-Python software releases, version numbers + for this field are **not** required to conform to the format specified in `PEP 386`_: they should correspond to the version scheme used by the external dependency. Any number of conditional operators can be specified, e.g. the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. - The canonical list of what strings are allowed is available - in the `Python Package Index`_ database: see - `External References Registry`_ below for a description of how - the allowed values are managed. - - Some dependencies are anticipated to be quite broad, eg. "C", - indicating a C compiler is required. + Notice that there's is no particular rule on the strings to be used. Examples:: @@ -427,26 +423,6 @@ `PEP 386`_. -External References Registry -============================ - -Stores in the `Python Package Index`_ database a list of (name, description, -URI) identifying an external reference that may be used as a value in -a Requires-External field. - -The name and description are required, but URI is not (as there is no -single useful URI for "C"). - -Submissions to the registry are open to the community, and may be performed -through the web or using the command-line. - -The names in the registry will be created under a first-comes first-wins -basis. Other packagers of Python software (eg. to deb, rpm, etc) should be -able to translate the `Requires-external` field to names in their own -packaging system. - -XXX command-line interface needs work, obviously - Environment markers =================== From nnorwitz at gmail.com Wed Nov 18 00:39:59 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 17 Nov 2009 18:39:59 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091117233959.GA32063@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_distutils leaked [-25, 0, 0] references, sum=-25 Less important issues: ---------------------- test_popen2 leaked [-29, 25, -25] references, sum=-29 From solipsis at pitrou.net Wed Nov 18 00:46:50 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 18 Nov 2009 00:46:50 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76341): sum=16 Message-ID: <20091117234650.1925D1780F@ns6635.ovh.net> py3k results for svn r76341 (hg cset 77a732a11f90) -------------------------------------------------- test_urllib leaked [8, 4, 4] references, sum=16 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogTLzQW-', '-x', 'test_httpservers'] From python-checkins at python.org Wed Nov 18 09:46:57 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 18 Nov 2009 08:46:57 -0000 Subject: [Python-checkins] r76358 - in python/trunk: Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Wed Nov 18 09:46:56 2009 New Revision: 76358 Log: #7293: distutils.test_msvc9compiler now uses a key that exists on any fresh windows install Modified: python/trunk/Lib/distutils/tests/test_msvc9compiler.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/trunk/Lib/distutils/tests/test_msvc9compiler.py Wed Nov 18 09:46:56 2009 @@ -44,17 +44,17 @@ # looking for values that should exist on all # windows registeries versions. - path = r'Software\Microsoft\Notepad' - v = Reg.get_value(path, u"lfitalic") - self.assertTrue(v in (0, 1)) + path = r'Control Panel\Desktop' + v = Reg.get_value(path, u'dragfullwindows') + self.assertTrue(v in (u'0', u'1')) import _winreg HKCU = _winreg.HKEY_CURRENT_USER keys = Reg.read_keys(HKCU, 'xxxx') self.assertEquals(keys, None) - keys = Reg.read_keys(HKCU, r'Software\Microsoft') - self.assertTrue('Notepad' in keys) + keys = Reg.read_keys(HKCU, r'Control Panel') + self.assertTrue('Desktop' in keys) def test_suite(): return unittest.makeSuite(msvc9compilerTestCase) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 18 09:46:56 2009 @@ -431,6 +431,9 @@ Library ------- +- Issue #7293: distutils.test_msvc9compiler is fixed to work on any fresh + Windows box. Help provided by David Bolen. + - Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch - Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using From python-checkins at python.org Wed Nov 18 09:52:10 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 18 Nov 2009 08:52:10 -0000 Subject: [Python-checkins] r76359 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Wed Nov 18 09:52:10 2009 New Revision: 76359 Log: Blocked revisions 76358 via svnmerge ........ r76358 | tarek.ziade | 2009-11-18 09:46:56 +0100 (Wed, 18 Nov 2009) | 1 line #7293: distutils.test_msvc9compiler now uses a key that exists on any fresh windows install ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Nov 18 10:32:35 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 18 Nov 2009 09:32:35 -0000 Subject: [Python-checkins] r76360 - in python/branches/py3k: Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Wed Nov 18 10:32:34 2009 New Revision: 76360 Log: Merged revisions 76358 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76358 | tarek.ziade | 2009-11-18 09:46:56 +0100 (Wed, 18 Nov 2009) | 1 line #7293: distutils.test_msvc9compiler now uses a key that exists on any fresh windows install ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Wed Nov 18 10:32:34 2009 @@ -44,17 +44,17 @@ # looking for values that should exist on all # windows registeries versions. - path = r'Software\Microsoft\Notepad' - v = Reg.get_value(path, "lfitalic") - self.assertTrue(v in (0, 1)) + path = r'Control Panel\Desktop' + v = Reg.get_value(path, 'dragfullwindows') + self.assertTrue(v in ('0', '1')) import winreg HKCU = winreg.HKEY_CURRENT_USER keys = Reg.read_keys(HKCU, 'xxxx') self.assertEquals(keys, None) - keys = Reg.read_keys(HKCU, r'Software\Microsoft') - self.assertTrue('Notepad' in keys) + keys = Reg.read_keys(HKCU, r'Control Panel') + self.assertTrue('Desktop' in keys) def test_suite(): return unittest.makeSuite(msvc9compilerTestCase) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Nov 18 10:32:34 2009 @@ -137,6 +137,9 @@ Library ------- +- Issue #7293: distutils.test_msvc9compiler is fixed to work on any fresh + Windows box. Help provided by David Bolen. + - Issue #2054: ftplib now provides an FTP_TLS class to do secure FTP using TLS or SSL. Patch by Giampaolo Rodola'. From python-checkins at python.org Wed Nov 18 11:19:38 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 18 Nov 2009 10:19:38 -0000 Subject: [Python-checkins] r76361 - in python/branches/release31-maint: Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Wed Nov 18 11:19:38 2009 New Revision: 76361 Log: Merged revisions 76360 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76360 | tarek.ziade | 2009-11-18 10:32:34 +0100 (Wed, 18 Nov 2009) | 9 lines Merged revisions 76358 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76358 | tarek.ziade | 2009-11-18 09:46:56 +0100 (Wed, 18 Nov 2009) | 1 line #7293: distutils.test_msvc9compiler now uses a key that exists on any fresh windows install ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py Wed Nov 18 11:19:38 2009 @@ -44,17 +44,17 @@ # looking for values that should exist on all # windows registeries versions. - path = r'Software\Microsoft\Notepad' - v = Reg.get_value(path, "lfitalic") - self.assertTrue(v in (0, 1)) + path = r'Control Panel\Desktop' + v = Reg.get_value(path, 'dragfullwindows') + self.assertTrue(v in ('0', '1')) import winreg HKCU = winreg.HKEY_CURRENT_USER keys = Reg.read_keys(HKCU, 'xxxx') self.assertEquals(keys, None) - keys = Reg.read_keys(HKCU, r'Software\Microsoft') - self.assertTrue('Notepad' in keys) + keys = Reg.read_keys(HKCU, r'Control Panel') + self.assertTrue('Desktop' in keys) def test_suite(): return unittest.makeSuite(msvc9compilerTestCase) Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Nov 18 11:19:38 2009 @@ -46,6 +46,9 @@ Library ------- +- Issue #7293: distutils.test_msvc9compiler is fixed to work on any fresh + Windows box. Help provided by David Bolen. + - Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch - Issue #7318: multiprocessing now uses a timeout when it fails to establish From python-checkins at python.org Wed Nov 18 12:27:53 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 18 Nov 2009 11:27:53 -0000 Subject: [Python-checkins] r76362 - python/trunk/Lib/test/test_runpy.py Message-ID: Author: nick.coghlan Date: Wed Nov 18 12:27:53 2009 New Revision: 76362 Log: Correctly escape arbitrary error message text in the runpy unit tests Modified: python/trunk/Lib/test/test_runpy.py Modified: python/trunk/Lib/test/test_runpy.py ============================================================================== --- python/trunk/Lib/test/test_runpy.py (original) +++ python/trunk/Lib/test/test_runpy.py Wed Nov 18 12:27:53 2009 @@ -3,6 +3,7 @@ import os import os.path import sys +import re import tempfile from test.test_support import verbose, run_unittest, forget from test.script_helper import (temp_dir, make_script, compile_script, @@ -317,8 +318,7 @@ self.assertEqual(result["__package__"], expected_package) def _check_import_error(self, script_name, msg): - # Double backslashes to handle path separators on Windows - msg = msg.replace("\\", "\\\\") + msg = re.escape(msg) self.assertRaisesRegexp(ImportError, msg, run_path, script_name) def test_basic_script(self): From python-checkins at python.org Wed Nov 18 12:29:43 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 18 Nov 2009 11:29:43 -0000 Subject: [Python-checkins] r76363 - python/branches/release26-maint Message-ID: Author: nick.coghlan Date: Wed Nov 18 12:29:42 2009 New Revision: 76363 Log: Blocked revisions 76362 via svnmerge ........ r76362 | nick.coghlan | 2009-11-18 21:27:53 +1000 (Wed, 18 Nov 2009) | 1 line Correctly escape arbitrary error message text in the runpy unit tests ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Nov 18 12:35:25 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 18 Nov 2009 11:35:25 -0000 Subject: [Python-checkins] r76364 - in python/branches/py3k: Lib/test/test_runpy.py Message-ID: Author: nick.coghlan Date: Wed Nov 18 12:35:25 2009 New Revision: 76364 Log: Merged revisions 76362 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76362 | nick.coghlan | 2009-11-18 21:27:53 +1000 (Wed, 18 Nov 2009) | 1 line Correctly escape arbitrary error message text in the runpy unit tests ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_runpy.py Modified: python/branches/py3k/Lib/test/test_runpy.py ============================================================================== --- python/branches/py3k/Lib/test/test_runpy.py (original) +++ python/branches/py3k/Lib/test/test_runpy.py Wed Nov 18 12:35:25 2009 @@ -3,6 +3,7 @@ import os import os.path import sys +import re import tempfile from test.support import verbose, run_unittest, forget from test.script_helper import (temp_dir, make_script, compile_script, @@ -290,8 +291,7 @@ self.assertEqual(result["__package__"], expected_package) def _check_import_error(self, script_name, msg): - # Double backslashes to handle path separators on Windows - msg = msg.replace("\\", "\\\\") + msg = re.escape(msg) self.assertRaisesRegexp(ImportError, msg, run_path, script_name) def test_basic_script(self): From python-checkins at python.org Wed Nov 18 12:39:26 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 18 Nov 2009 11:39:26 -0000 Subject: [Python-checkins] r76365 - python/branches/release31-maint Message-ID: Author: nick.coghlan Date: Wed Nov 18 12:39:26 2009 New Revision: 76365 Log: Blocked revisions 76364 via svnmerge ................ r76364 | nick.coghlan | 2009-11-18 21:35:25 +1000 (Wed, 18 Nov 2009) | 9 lines Merged revisions 76362 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76362 | nick.coghlan | 2009-11-18 21:27:53 +1000 (Wed, 18 Nov 2009) | 1 line Correctly escape arbitrary error message text in the runpy unit tests ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Wed Nov 18 19:52:24 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 18:52:24 -0000 Subject: [Python-checkins] r76366 - python/trunk/Doc/whatsnew/2.6.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 19:52:23 2009 New Revision: 76366 Log: Make separate section for deprecations in 2.6 whatsnew. Modified: python/trunk/Doc/whatsnew/2.6.rst Modified: python/trunk/Doc/whatsnew/2.6.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.6.rst (original) +++ python/trunk/Doc/whatsnew/2.6.rst Wed Nov 18 19:52:23 2009 @@ -1629,11 +1629,6 @@ :cfunc:`PyObject_HashNotImplemented`. (Fixed by Nick Coghlan and Amaury Forgeot d'Arc; :issue:`2235`.) -* Changes to the :class:`Exception` interface - as dictated by :pep:`352` continue to be made. For 2.6, - the :attr:`message` attribute is being deprecated in favor of the - :attr:`args` attribute. - * The :exc:`GeneratorExit` exception now subclasses :exc:`BaseException` instead of :exc:`Exception`. This means that an exception handler that does ``except Exception:`` @@ -1770,8 +1765,8 @@ .. ====================================================================== -New, Improved, and Deprecated Modules -===================================== +New and Improved Modules +======================== As in every release, Python's standard library received a number of enhancements and bug fixes. Here's a partial list of the most notable @@ -1779,36 +1774,6 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. -* (3.0-warning mode) Python 3.0 will feature a reorganized standard - library that will drop many outdated modules and rename others. - Python 2.6 running in 3.0-warning mode will warn about these modules - when they are imported. - - The list of deprecated modules is: - :mod:`audiodev`, - :mod:`bgenlocations`, - :mod:`buildtools`, - :mod:`bundlebuilder`, - :mod:`Canvas`, - :mod:`compiler`, - :mod:`dircache`, - :mod:`dl`, - :mod:`fpformat`, - :mod:`gensuitemodule`, - :mod:`ihooks`, - :mod:`imageop`, - :mod:`imgfile`, - :mod:`linuxaudiodev`, - :mod:`mhlib`, - :mod:`mimetools`, - :mod:`multifile`, - :mod:`new`, - :mod:`pure`, - :mod:`statvfs`, - :mod:`sunaudiodev`, - :mod:`test.testall`, and - :mod:`toaiff`. - * The :mod:`asyncore` and :mod:`asynchat` modules are being actively maintained again, and a number of patches and bugfixes were applied. (Maintained by Josiah Carlson; see :issue:`1736190` for @@ -1993,8 +1958,6 @@ a Unicode path was used and Unicode filenames are matched within the directory. (:issue:`1001604`) -* The :mod:`gopherlib` module has been removed. - * A new function in the :mod:`heapq` module, ``merge(iter1, iter2, ...)``, takes any number of iterables returning data in sorted order, and returns a new generator that returns the contents of all @@ -2154,13 +2117,6 @@ (Contributed by Christian Heimes and Mark Dickinson.) -* The :mod:`MimeWriter` module and :mod:`mimify` module - have been deprecated; use the :mod:`email` - package instead. - -* The :mod:`md5` module has been deprecated; use the :mod:`hashlib` module - instead. - * :class:`mmap` objects now have a :meth:`rfind` method that searches for a substring beginning at the end of the string and searching backwards. The :meth:`find` method also gained an *end* parameter @@ -2243,10 +2199,7 @@ and can optionally take new command-line arguments for the program. (Contributed by Rocky Bernstein; :issue:`1393667`.) -* The :mod:`posixfile` module has been deprecated; :func:`fcntl.lockf` - provides better locking. - - The :func:`post_mortem` function, used to begin debugging a +* The :func:`pdb.post_mortem` function, used to begin debugging a traceback, will now use the traceback returned by :func:`sys.exc_info` if no traceback is supplied. (Contributed by Facundo Batista; :issue:`1106316`.) @@ -2256,9 +2209,6 @@ opcodes, returning a shorter pickle that contains the same data structure. (Contributed by Raymond Hettinger.) -* The :mod:`popen2` module has been deprecated; use the :mod:`subprocess` - module. - * A :func:`get_data` function was added to the :mod:`pkgutil` module that returns the contents of resource files included with an installed Python package. For example:: @@ -2314,8 +2264,6 @@ (Contributed by Guido van Rossum from work for Google App Engine; :issue:`3487`.) -* The :mod:`rgbimg` module has been removed. - * The :mod:`rlcompleter` module's :meth:`Completer.complete()` method will now ignore exceptions triggered while evaluating a name. (Fixed by Lorenz Quack; :issue:`2250`.) @@ -2334,12 +2282,6 @@ for that file. (Contributed by Christian Heimes; :issue:`1657`.) -* The :mod:`sets` module has been deprecated; it's better to - use the built-in :class:`set` and :class:`frozenset` types. - -* The :mod:`sha` module has been deprecated; use the :mod:`hashlib` module - instead. - * The :func:`shutil.copytree` function now has an optional *ignore* argument that takes a callable object. This callable will receive each directory path and a list of the directory's contents, and returns a list of names that @@ -2402,7 +2344,7 @@ e-mail between agents that don't manage a mail queue. (LMTP implemented by Leif Hedstrom; :issue:`957003`.) - SMTP.starttls() now complies with :rfc:`3207` and forgets any + :meth:`SMTP.starttls` now complies with :rfc:`3207` and forgets any knowledge obtained from the server not obtained from the TLS negotiation itself. (Patch contributed by Bill Fenner; :issue:`829951`.) @@ -2951,6 +2893,73 @@ .. ====================================================================== +Deprecations and Removals +========================= + +* String exceptions have been removed. Attempting to use them raises a + :exc:`TypeError`. + +* Changes to the :class:`Exception` interface + as dictated by :pep:`352` continue to be made. For 2.6, + the :attr:`message` attribute is being deprecated in favor of the + :attr:`args` attribute. + +* (3.0-warning mode) Python 3.0 will feature a reorganized standard + library that will drop many outdated modules and rename others. + Python 2.6 running in 3.0-warning mode will warn about these modules + when they are imported. + + The list of deprecated modules is: + :mod:`audiodev`, + :mod:`bgenlocations`, + :mod:`buildtools`, + :mod:`bundlebuilder`, + :mod:`Canvas`, + :mod:`compiler`, + :mod:`dircache`, + :mod:`dl`, + :mod:`fpformat`, + :mod:`gensuitemodule`, + :mod:`ihooks`, + :mod:`imageop`, + :mod:`imgfile`, + :mod:`linuxaudiodev`, + :mod:`mhlib`, + :mod:`mimetools`, + :mod:`multifile`, + :mod:`new`, + :mod:`pure`, + :mod:`statvfs`, + :mod:`sunaudiodev`, + :mod:`test.testall`, and + :mod:`toaiff`. + +* The :mod:`gopherlib` module has been removed. + +* The :mod:`MimeWriter` module and :mod:`mimify` module + have been deprecated; use the :mod:`email` + package instead. + +* The :mod:`md5` module has been deprecated; use the :mod:`hashlib` module + instead. + +* The :mod:`posixfile` module has been deprecated; :func:`fcntl.lockf` + provides better locking. + +* The :mod:`popen2` module has been deprecated; use the :mod:`subprocess` + module. + +* The :mod:`rgbimg` module has been removed. + +* The :mod:`sets` module has been deprecated; it's better to + use the built-in :class:`set` and :class:`frozenset` types. + +* The :mod:`sha` module has been deprecated; use the :mod:`hashlib` module + instead. + + +.. ====================================================================== + Build and C API Changes ======================= From python-checkins at python.org Wed Nov 18 19:52:35 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 18:52:35 -0000 Subject: [Python-checkins] r76367 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 19:52:35 2009 New Revision: 76367 Log: Make separate section for deprecations in 2.7 whatsnew. Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Wed Nov 18 19:52:35 2009 @@ -413,8 +413,8 @@ .. ====================================================================== -New, Improved, and Deprecated Modules -===================================== +New and Improved Modules +======================== As in every release, Python's standard library received a number of enhancements and bug fixes. Here's a partial list of the most notable @@ -891,6 +891,14 @@ inclusion in :issue:`2618`, but the authors argued that Guilherme Polo's work was more comprehensive. + +Deprecations and Removals +========================= + +* :func:`contextlib.nested`, which allows handling more than one context manager + with one :keyword:`with` statement, has been deprecated; :keyword:`with` + supports multiple context managers syntactically now. + .. ====================================================================== From python-checkins at python.org Wed Nov 18 19:53:14 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 18:53:14 -0000 Subject: [Python-checkins] r76368 - in python/branches/py3k: Doc/whatsnew/2.7.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 19:53:14 2009 New Revision: 76368 Log: Merged revisions 76367 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76367 | georg.brandl | 2009-11-18 18:52:35 +0000 (Mi, 18 Nov 2009) | 1 line Make separate section for deprecations in 2.7 whatsnew. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/whatsnew/2.7.rst Modified: python/branches/py3k/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.7.rst Wed Nov 18 19:53:14 2009 @@ -229,8 +229,8 @@ .. ====================================================================== -New, Improved, and Deprecated Modules -===================================== +New and Improved Modules +======================== As in every release, Python's standard library received a number of enhancements and bug fixes. Here's a partial list of the most notable @@ -590,6 +590,14 @@ inclusion in :issue:`2618`, but the authors argued that Guilherme Polo's work was more comprehensive. + +Deprecations and Removals +========================= + +* :func:`contextlib.nested`, which allows handling more than one context manager + with one :keyword:`with` statement, has been deprecated; :keyword:`with` + supports multiple context managers syntactically now. + .. ====================================================================== From python-checkins at python.org Wed Nov 18 19:53:55 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 18:53:55 -0000 Subject: [Python-checkins] r76369 - in python/branches/py3k: Doc/whatsnew/2.6.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 19:53:54 2009 New Revision: 76369 Log: Merged revisions 76366 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76366 | georg.brandl | 2009-11-18 18:52:23 +0000 (Mi, 18 Nov 2009) | 1 line Make separate section for deprecations in 2.6 whatsnew. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/whatsnew/2.6.rst Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Wed Nov 18 19:53:54 2009 @@ -1633,11 +1633,6 @@ :cfunc:`PyObject_HashNotImplemented`. (Fixed by Nick Coghlan and Amaury Forgeot d'Arc; :issue:`2235`.) -* Changes to the :class:`Exception` interface - as dictated by :pep:`352` continue to be made. For 2.6, - the :attr:`message` attribute is being deprecated in favor of the - :attr:`args` attribute. - * The :exc:`GeneratorExit` exception now subclasses :exc:`BaseException` instead of :exc:`Exception`. This means that an exception handler that does ``except Exception:`` @@ -1774,8 +1769,8 @@ .. ====================================================================== -New, Improved, and Deprecated Modules -===================================== +New and Improved Modules +======================== As in every release, Python's standard library received a number of enhancements and bug fixes. Here's a partial list of the most notable @@ -1783,36 +1778,6 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. -* (3.0-warning mode) Python 3.0 will feature a reorganized standard - library that will drop many outdated modules and rename others. - Python 2.6 running in 3.0-warning mode will warn about these modules - when they are imported. - - The list of deprecated modules is: - :mod:`audiodev`, - :mod:`bgenlocations`, - :mod:`buildtools`, - :mod:`bundlebuilder`, - :mod:`Canvas`, - :mod:`compiler`, - :mod:`dircache`, - :mod:`dl`, - :mod:`fpformat`, - :mod:`gensuitemodule`, - :mod:`ihooks`, - :mod:`imageop`, - :mod:`imgfile`, - :mod:`linuxaudiodev`, - :mod:`mhlib`, - :mod:`mimetools`, - :mod:`multifile`, - :mod:`new`, - :mod:`pure`, - :mod:`statvfs`, - :mod:`sunaudiodev`, - :mod:`test.testall`, and - :mod:`toaiff`. - * The :mod:`asyncore` and :mod:`asynchat` modules are being actively maintained again, and a number of patches and bugfixes were applied. (Maintained by Josiah Carlson; see :issue:`1736190` for @@ -1997,8 +1962,6 @@ a Unicode path was used and Unicode filenames are matched within the directory. (:issue:`1001604`) -* The :mod:`gopherlib` module has been removed. - * A new function in the :mod:`heapq` module, ``merge(iter1, iter2, ...)``, takes any number of iterables returning data in sorted order, and returns a new generator that returns the contents of all @@ -2158,13 +2121,6 @@ (Contributed by Christian Heimes and Mark Dickinson.) -* The :mod:`MimeWriter` module and :mod:`mimify` module - have been deprecated; use the :mod:`email` - package instead. - -* The :mod:`md5` module has been deprecated; use the :mod:`hashlib` module - instead. - * :class:`mmap` objects now have a :meth:`rfind` method that searches for a substring beginning at the end of the string and searching backwards. The :meth:`find` method also gained an *end* parameter @@ -2247,10 +2203,7 @@ and can optionally take new command-line arguments for the program. (Contributed by Rocky Bernstein; :issue:`1393667`.) -* The :mod:`posixfile` module has been deprecated; :func:`fcntl.lockf` - provides better locking. - - The :func:`post_mortem` function, used to begin debugging a +* The :func:`pdb.post_mortem` function, used to begin debugging a traceback, will now use the traceback returned by :func:`sys.exc_info` if no traceback is supplied. (Contributed by Facundo Batista; :issue:`1106316`.) @@ -2260,9 +2213,6 @@ opcodes, returning a shorter pickle that contains the same data structure. (Contributed by Raymond Hettinger.) -* The :mod:`popen2` module has been deprecated; use the :mod:`subprocess` - module. - * A :func:`get_data` function was added to the :mod:`pkgutil` module that returns the contents of resource files included with an installed Python package. For example:: @@ -2318,8 +2268,6 @@ (Contributed by Guido van Rossum from work for Google App Engine; :issue:`3487`.) -* The :mod:`rgbimg` module has been removed. - * The :mod:`rlcompleter` module's :meth:`Completer.complete()` method will now ignore exceptions triggered while evaluating a name. (Fixed by Lorenz Quack; :issue:`2250`.) @@ -2338,12 +2286,6 @@ for that file. (Contributed by Christian Heimes; :issue:`1657`.) -* The :mod:`sets` module has been deprecated; it's better to - use the built-in :class:`set` and :class:`frozenset` types. - -* The :mod:`sha` module has been deprecated; use the :mod:`hashlib` module - instead. - * The :func:`shutil.copytree` function now has an optional *ignore* argument that takes a callable object. This callable will receive each directory path and a list of the directory's contents, and returns a list of names that @@ -2406,7 +2348,7 @@ e-mail between agents that don't manage a mail queue. (LMTP implemented by Leif Hedstrom; :issue:`957003`.) - SMTP.starttls() now complies with :rfc:`3207` and forgets any + :meth:`SMTP.starttls` now complies with :rfc:`3207` and forgets any knowledge obtained from the server not obtained from the TLS negotiation itself. (Patch contributed by Bill Fenner; :issue:`829951`.) @@ -2955,6 +2897,73 @@ .. ====================================================================== +Deprecations and Removals +========================= + +* String exceptions have been removed. Attempting to use them raises a + :exc:`TypeError`. + +* Changes to the :class:`Exception` interface + as dictated by :pep:`352` continue to be made. For 2.6, + the :attr:`message` attribute is being deprecated in favor of the + :attr:`args` attribute. + +* (3.0-warning mode) Python 3.0 will feature a reorganized standard + library that will drop many outdated modules and rename others. + Python 2.6 running in 3.0-warning mode will warn about these modules + when they are imported. + + The list of deprecated modules is: + :mod:`audiodev`, + :mod:`bgenlocations`, + :mod:`buildtools`, + :mod:`bundlebuilder`, + :mod:`Canvas`, + :mod:`compiler`, + :mod:`dircache`, + :mod:`dl`, + :mod:`fpformat`, + :mod:`gensuitemodule`, + :mod:`ihooks`, + :mod:`imageop`, + :mod:`imgfile`, + :mod:`linuxaudiodev`, + :mod:`mhlib`, + :mod:`mimetools`, + :mod:`multifile`, + :mod:`new`, + :mod:`pure`, + :mod:`statvfs`, + :mod:`sunaudiodev`, + :mod:`test.testall`, and + :mod:`toaiff`. + +* The :mod:`gopherlib` module has been removed. + +* The :mod:`MimeWriter` module and :mod:`mimify` module + have been deprecated; use the :mod:`email` + package instead. + +* The :mod:`md5` module has been deprecated; use the :mod:`hashlib` module + instead. + +* The :mod:`posixfile` module has been deprecated; :func:`fcntl.lockf` + provides better locking. + +* The :mod:`popen2` module has been deprecated; use the :mod:`subprocess` + module. + +* The :mod:`rgbimg` module has been removed. + +* The :mod:`sets` module has been deprecated; it's better to + use the built-in :class:`set` and :class:`frozenset` types. + +* The :mod:`sha` module has been deprecated; use the :mod:`hashlib` module + instead. + + +.. ====================================================================== + Build and C API Changes ======================= From python-checkins at python.org Wed Nov 18 19:54:00 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 18:54:00 -0000 Subject: [Python-checkins] r76370 - python/branches/release26-maint Message-ID: Author: georg.brandl Date: Wed Nov 18 19:53:59 2009 New Revision: 76370 Log: Blocked revisions 76367 via svnmerge ........ r76367 | georg.brandl | 2009-11-18 18:52:35 +0000 (Mi, 18 Nov 2009) | 1 line Make separate section for deprecations in 2.7 whatsnew. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Nov 18 19:54:21 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 18:54:21 -0000 Subject: [Python-checkins] r76371 - in python/branches/release26-maint: Doc/whatsnew/2.6.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 19:54:21 2009 New Revision: 76371 Log: Merged revisions 76366 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76366 | georg.brandl | 2009-11-18 18:52:23 +0000 (Mi, 18 Nov 2009) | 1 line Make separate section for deprecations in 2.6 whatsnew. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/whatsnew/2.6.rst Modified: python/branches/release26-maint/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/release26-maint/Doc/whatsnew/2.6.rst (original) +++ python/branches/release26-maint/Doc/whatsnew/2.6.rst Wed Nov 18 19:54:21 2009 @@ -1629,11 +1629,6 @@ :cfunc:`PyObject_HashNotImplemented`. (Fixed by Nick Coghlan and Amaury Forgeot d'Arc; :issue:`2235`.) -* Changes to the :class:`Exception` interface - as dictated by :pep:`352` continue to be made. For 2.6, - the :attr:`message` attribute is being deprecated in favor of the - :attr:`args` attribute. - * The :exc:`GeneratorExit` exception now subclasses :exc:`BaseException` instead of :exc:`Exception`. This means that an exception handler that does ``except Exception:`` @@ -1770,8 +1765,8 @@ .. ====================================================================== -New, Improved, and Deprecated Modules -===================================== +New and Improved Modules +======================== As in every release, Python's standard library received a number of enhancements and bug fixes. Here's a partial list of the most notable @@ -1779,36 +1774,6 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. -* (3.0-warning mode) Python 3.0 will feature a reorganized standard - library that will drop many outdated modules and rename others. - Python 2.6 running in 3.0-warning mode will warn about these modules - when they are imported. - - The list of deprecated modules is: - :mod:`audiodev`, - :mod:`bgenlocations`, - :mod:`buildtools`, - :mod:`bundlebuilder`, - :mod:`Canvas`, - :mod:`compiler`, - :mod:`dircache`, - :mod:`dl`, - :mod:`fpformat`, - :mod:`gensuitemodule`, - :mod:`ihooks`, - :mod:`imageop`, - :mod:`imgfile`, - :mod:`linuxaudiodev`, - :mod:`mhlib`, - :mod:`mimetools`, - :mod:`multifile`, - :mod:`new`, - :mod:`pure`, - :mod:`statvfs`, - :mod:`sunaudiodev`, - :mod:`test.testall`, and - :mod:`toaiff`. - * The :mod:`asyncore` and :mod:`asynchat` modules are being actively maintained again, and a number of patches and bugfixes were applied. (Maintained by Josiah Carlson; see :issue:`1736190` for @@ -1993,8 +1958,6 @@ a Unicode path was used and Unicode filenames are matched within the directory. (:issue:`1001604`) -* The :mod:`gopherlib` module has been removed. - * A new function in the :mod:`heapq` module, ``merge(iter1, iter2, ...)``, takes any number of iterables returning data in sorted order, and returns a new generator that returns the contents of all @@ -2154,13 +2117,6 @@ (Contributed by Christian Heimes and Mark Dickinson.) -* The :mod:`MimeWriter` module and :mod:`mimify` module - have been deprecated; use the :mod:`email` - package instead. - -* The :mod:`md5` module has been deprecated; use the :mod:`hashlib` module - instead. - * :class:`mmap` objects now have a :meth:`rfind` method that searches for a substring beginning at the end of the string and searching backwards. The :meth:`find` method also gained an *end* parameter @@ -2243,10 +2199,7 @@ and can optionally take new command-line arguments for the program. (Contributed by Rocky Bernstein; :issue:`1393667`.) -* The :mod:`posixfile` module has been deprecated; :func:`fcntl.lockf` - provides better locking. - - The :func:`post_mortem` function, used to begin debugging a +* The :func:`pdb.post_mortem` function, used to begin debugging a traceback, will now use the traceback returned by :func:`sys.exc_info` if no traceback is supplied. (Contributed by Facundo Batista; :issue:`1106316`.) @@ -2256,9 +2209,6 @@ opcodes, returning a shorter pickle that contains the same data structure. (Contributed by Raymond Hettinger.) -* The :mod:`popen2` module has been deprecated; use the :mod:`subprocess` - module. - * A :func:`get_data` function was added to the :mod:`pkgutil` module that returns the contents of resource files included with an installed Python package. For example:: @@ -2314,8 +2264,6 @@ (Contributed by Guido van Rossum from work for Google App Engine; :issue:`3487`.) -* The :mod:`rgbimg` module has been removed. - * The :mod:`rlcompleter` module's :meth:`Completer.complete()` method will now ignore exceptions triggered while evaluating a name. (Fixed by Lorenz Quack; :issue:`2250`.) @@ -2334,12 +2282,6 @@ for that file. (Contributed by Christian Heimes; :issue:`1657`.) -* The :mod:`sets` module has been deprecated; it's better to - use the built-in :class:`set` and :class:`frozenset` types. - -* The :mod:`sha` module has been deprecated; use the :mod:`hashlib` module - instead. - * The :func:`shutil.copytree` function now has an optional *ignore* argument that takes a callable object. This callable will receive each directory path and a list of the directory's contents, and returns a list of names that @@ -2402,7 +2344,7 @@ e-mail between agents that don't manage a mail queue. (LMTP implemented by Leif Hedstrom; :issue:`957003`.) - SMTP.starttls() now complies with :rfc:`3207` and forgets any + :meth:`SMTP.starttls` now complies with :rfc:`3207` and forgets any knowledge obtained from the server not obtained from the TLS negotiation itself. (Patch contributed by Bill Fenner; :issue:`829951`.) @@ -2951,6 +2893,73 @@ .. ====================================================================== +Deprecations and Removals +========================= + +* String exceptions have been removed. Attempting to use them raises a + :exc:`TypeError`. + +* Changes to the :class:`Exception` interface + as dictated by :pep:`352` continue to be made. For 2.6, + the :attr:`message` attribute is being deprecated in favor of the + :attr:`args` attribute. + +* (3.0-warning mode) Python 3.0 will feature a reorganized standard + library that will drop many outdated modules and rename others. + Python 2.6 running in 3.0-warning mode will warn about these modules + when they are imported. + + The list of deprecated modules is: + :mod:`audiodev`, + :mod:`bgenlocations`, + :mod:`buildtools`, + :mod:`bundlebuilder`, + :mod:`Canvas`, + :mod:`compiler`, + :mod:`dircache`, + :mod:`dl`, + :mod:`fpformat`, + :mod:`gensuitemodule`, + :mod:`ihooks`, + :mod:`imageop`, + :mod:`imgfile`, + :mod:`linuxaudiodev`, + :mod:`mhlib`, + :mod:`mimetools`, + :mod:`multifile`, + :mod:`new`, + :mod:`pure`, + :mod:`statvfs`, + :mod:`sunaudiodev`, + :mod:`test.testall`, and + :mod:`toaiff`. + +* The :mod:`gopherlib` module has been removed. + +* The :mod:`MimeWriter` module and :mod:`mimify` module + have been deprecated; use the :mod:`email` + package instead. + +* The :mod:`md5` module has been deprecated; use the :mod:`hashlib` module + instead. + +* The :mod:`posixfile` module has been deprecated; :func:`fcntl.lockf` + provides better locking. + +* The :mod:`popen2` module has been deprecated; use the :mod:`subprocess` + module. + +* The :mod:`rgbimg` module has been removed. + +* The :mod:`sets` module has been deprecated; it's better to + use the built-in :class:`set` and :class:`frozenset` types. + +* The :mod:`sha` module has been deprecated; use the :mod:`hashlib` module + instead. + + +.. ====================================================================== + Build and C API Changes ======================= From python-checkins at python.org Wed Nov 18 20:21:12 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 18 Nov 2009 19:21:12 -0000 Subject: [Python-checkins] r76372 - python/branches/release30-maint/Doc/whatsnew/3.0.rst Message-ID: Author: raymond.hettinger Date: Wed Nov 18 20:21:11 2009 New Revision: 76372 Log: Issue 7343: notes on {} formatting versus % formatting Modified: python/branches/release30-maint/Doc/whatsnew/3.0.rst Modified: python/branches/release30-maint/Doc/whatsnew/3.0.rst ============================================================================== --- python/branches/release30-maint/Doc/whatsnew/3.0.rst (original) +++ python/branches/release30-maint/Doc/whatsnew/3.0.rst Wed Nov 18 20:21:11 2009 @@ -488,8 +488,8 @@ :meth:`format` method for both 8-bit and Unicode strings. In 3.0, only the :class:`str` type (text strings with Unicode support) supports this method; the :class:`bytes` type does not. The plan is - to eventually make this the only API for string formatting, and to - start deprecating the ``%`` operator in Python 3.1. + to make this the preferred API for string formatting and to + de-emphasize the ``%`` string formatting operator. * :ref:`pep-3105`. This is now a standard feature and no longer needs to be imported from :mod:`__future__`. More details were given above. From python-checkins at python.org Wed Nov 18 20:33:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 19:33:36 -0000 Subject: [Python-checkins] r76373 - in python/trunk: Include/floatobject.h Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Python/bltinmodule.c Message-ID: Author: mark.dickinson Date: Wed Nov 18 20:33:35 2009 New Revision: 76373 Log: Issue #7117, continued: Change round implementation to use the correctly-rounded string <-> float conversions; this makes sure that the result of the round operation is correctly rounded, and hence displays nicely using the new float repr. Modified: python/trunk/Include/floatobject.h python/trunk/Lib/test/test_float.py python/trunk/Misc/NEWS python/trunk/Objects/floatobject.c python/trunk/Python/bltinmodule.c Modified: python/trunk/Include/floatobject.h ============================================================================== --- python/trunk/Include/floatobject.h (original) +++ python/trunk/Include/floatobject.h Wed Nov 18 20:33:35 2009 @@ -127,6 +127,13 @@ char *format_spec, Py_ssize_t format_spec_len); +/* Round a C double x to the closest multiple of 10**-ndigits. Returns a + Python float on success, or NULL (with an appropriate exception set) on + failure. Used in builtin_round in bltinmodule.c. */ +PyAPI_FUNC(PyObject *) _Py_double_round(double x, int ndigits); + + + #ifdef __cplusplus } #endif Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Wed Nov 18 20:33:35 2009 @@ -5,7 +5,9 @@ import math from math import isinf, isnan, copysign, ldexp import operator -import random, fractions +import random +import fractions +import sys INF = float("inf") NAN = float("nan") @@ -339,6 +341,141 @@ self.assertEqual(v, eval(repr(v))) floats_file.close() + at unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") +class RoundTestCase(unittest.TestCase): + def test_second_argument_type(self): + # any type with an __index__ method should be permitted as + # a second argument + self.assertAlmostEqual(round(12.34, True), 12.3) + + class MyIndex(object): + def __index__(self): return 4 + self.assertAlmostEqual(round(-0.123456, MyIndex()), -0.1235) + # but floats should be illegal + self.assertRaises(TypeError, round, 3.14159, 2.0) + + def test_inf_nan(self): + # rounding an infinity or nan returns the same number; + # (in py3k, rounding an infinity or nan raises an error, + # since the result can't be represented as a long). + self.assertEqual(round(INF), INF) + self.assertEqual(round(-INF), -INF) + self.assertTrue(math.isnan(round(NAN))) + for n in range(-5, 5): + self.assertEqual(round(INF, n), INF) + self.assertEqual(round(-INF, n), -INF) + self.assertTrue(math.isnan(round(NAN, n))) + + def test_large_n(self): + for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]: + self.assertEqual(round(123.456, n), 123.456) + self.assertEqual(round(-123.456, n), -123.456) + self.assertEqual(round(1e300, n), 1e300) + self.assertEqual(round(1e-320, n), 1e-320) + self.assertEqual(round(1e150, 300), 1e150) + self.assertEqual(round(1e300, 307), 1e300) + self.assertEqual(round(-3.1415, 308), -3.1415) + self.assertEqual(round(1e150, 309), 1e150) + self.assertEqual(round(1.4e-315, 315), 1e-315) + + def test_small_n(self): + for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]: + self.assertEqual(round(123.456, n), 0.0) + self.assertEqual(round(-123.456, n), -0.0) + self.assertEqual(round(1e300, n), 0.0) + self.assertEqual(round(1e-320, n), 0.0) + + def test_overflow(self): + self.assertRaises(OverflowError, round, 1.6e308, -308) + self.assertRaises(OverflowError, round, -1.7e308, -308) + + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', + "test applies only when using short float repr style") + def test_previous_round_bugs(self): + # particular cases that have occurred in bug reports + self.assertEqual(round(562949953421312.5, 1), + 562949953421312.5) + self.assertEqual(round(56294995342131.5, 3), + 56294995342131.5) + + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', + "test applies only when using short float repr style") + def test_halfway_cases(self): + # Halfway cases need special attention, since the current + # implementation has to deal with them specially. Note that + # 2.x rounds halfway values up (i.e., away from zero) while + # 3.x does round-half-to-even. + self.assertAlmostEqual(round(0.125, 2), 0.13) + self.assertAlmostEqual(round(0.375, 2), 0.38) + self.assertAlmostEqual(round(0.625, 2), 0.63) + self.assertAlmostEqual(round(0.875, 2), 0.88) + self.assertAlmostEqual(round(-0.125, 2), -0.13) + self.assertAlmostEqual(round(-0.375, 2), -0.38) + self.assertAlmostEqual(round(-0.625, 2), -0.63) + self.assertAlmostEqual(round(-0.875, 2), -0.88) + + self.assertAlmostEqual(round(0.25, 1), 0.3) + self.assertAlmostEqual(round(0.75, 1), 0.8) + self.assertAlmostEqual(round(-0.25, 1), -0.3) + self.assertAlmostEqual(round(-0.75, 1), -0.8) + + self.assertEqual(round(-6.5, 0), -7.0) + self.assertEqual(round(-5.5, 0), -6.0) + self.assertEqual(round(-1.5, 0), -2.0) + self.assertEqual(round(-0.5, 0), -1.0) + self.assertEqual(round(0.5, 0), 1.0) + self.assertEqual(round(1.5, 0), 2.0) + self.assertEqual(round(2.5, 0), 3.0) + self.assertEqual(round(3.5, 0), 4.0) + self.assertEqual(round(4.5, 0), 5.0) + self.assertEqual(round(5.5, 0), 6.0) + self.assertEqual(round(6.5, 0), 7.0) + + # same but without an explicit second argument; in 3.x these + # will give integers + self.assertEqual(round(-6.5), -7.0) + self.assertEqual(round(-5.5), -6.0) + self.assertEqual(round(-1.5), -2.0) + self.assertEqual(round(-0.5), -1.0) + self.assertEqual(round(0.5), 1.0) + self.assertEqual(round(1.5), 2.0) + self.assertEqual(round(2.5), 3.0) + self.assertEqual(round(3.5), 4.0) + self.assertEqual(round(4.5), 5.0) + self.assertEqual(round(5.5), 6.0) + self.assertEqual(round(6.5), 7.0) + + self.assertEqual(round(-25.0, -1), -30.0) + self.assertEqual(round(-15.0, -1), -20.0) + self.assertEqual(round(-5.0, -1), -10.0) + self.assertEqual(round(5.0, -1), 10.0) + self.assertEqual(round(15.0, -1), 20.0) + self.assertEqual(round(25.0, -1), 30.0) + self.assertEqual(round(35.0, -1), 40.0) + self.assertEqual(round(45.0, -1), 50.0) + self.assertEqual(round(55.0, -1), 60.0) + self.assertEqual(round(65.0, -1), 70.0) + self.assertEqual(round(75.0, -1), 80.0) + self.assertEqual(round(85.0, -1), 90.0) + self.assertEqual(round(95.0, -1), 100.0) + self.assertEqual(round(12325.0, -1), 12330.0) + + self.assertEqual(round(350.0, -2), 400.0) + self.assertEqual(round(450.0, -2), 500.0) + + self.assertAlmostEqual(round(0.5e21, -21), 1e21) + self.assertAlmostEqual(round(1.5e21, -21), 2e21) + self.assertAlmostEqual(round(2.5e21, -21), 3e21) + self.assertAlmostEqual(round(5.5e21, -21), 6e21) + self.assertAlmostEqual(round(8.5e21, -21), 9e21) + + self.assertAlmostEqual(round(-1.5e22, -22), -2e22) + self.assertAlmostEqual(round(-0.5e22, -22), -1e22) + self.assertAlmostEqual(round(0.5e22, -22), 1e22) + self.assertAlmostEqual(round(1.5e22, -22), 2e22) + + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan class InfNanTest(unittest.TestCase): @@ -859,6 +996,7 @@ UnknownFormatTestCase, IEEEFormatTestCase, ReprTestCase, + RoundTestCase, InfNanTest, HexFloatTestCase, ) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 18 20:33:35 2009 @@ -12,6 +12,15 @@ Core and Builtins ----------------- +- Issue #7117: Backport round implementation from Python 3.x. round + now uses David Gay's correctly-rounded string <-> double conversions + (when available), and so produces correctly rounded results. There + are two related small changes: (1) round now accepts any class with + an __index__ method for its second argument (but no longer accepts + floats for the second argument), and (2) an excessively large second + integer argument (e.g., round(1.234, 10**100)) no longer raises an + exception. + - Issue #1757126: Fix the cyrillic-asian alias for the ptcp154 encoding. - Fix several issues with compile(). The input can now contain Windows and Mac Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Wed Nov 18 20:33:35 2009 @@ -999,6 +999,202 @@ return PyLong_FromDouble(x); } +/* _Py_double_round: rounds a finite nonzero double to the closest multiple of + 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <= + ndigits <= 323). Returns a Python float, or sets a Python error and + returns NULL on failure (OverflowError and memory errors are possible). */ + +#ifndef PY_NO_SHORT_FLOAT_REPR +/* version of _Py_double_round that uses the correctly-rounded string<->double + conversions from Python/dtoa.c */ + +/* FIVE_POW_LIMIT is the largest k such that 5**k is exactly representable as + a double. Since we're using the code in Python/dtoa.c, it should be safe + to assume that C doubles are IEEE 754 binary64 format. To be on the safe + side, we check this. */ +#if DBL_MANT_DIG == 53 +#define FIVE_POW_LIMIT 22 +#else +#error "C doubles do not appear to be IEEE 754 binary64 format" +#endif + +PyObject * +_Py_double_round(double x, int ndigits) { + + double rounded, m; + Py_ssize_t buflen, mybuflen=100; + char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf; + int decpt, sign, val, halfway_case; + PyObject *result = NULL; + + /* The basic idea is very simple: convert and round the double to a + decimal string using _Py_dg_dtoa, then convert that decimal string + back to a double with _Py_dg_strtod. There's one minor difficulty: + Python 2.x expects round to do round-half-away-from-zero, while + _Py_dg_dtoa does round-half-to-even. So we need some way to detect + and correct the halfway cases. + + Detection: a halfway value has the form k * 0.5 * 10**-ndigits for + some odd integer k. Or in other words, a rational number x is + exactly halfway between two multiples of 10**-ndigits if its + 2-valuation is exactly -ndigits-1 and its 5-valuation is at least + -ndigits. For ndigits >= 0 the latter condition is automatically + satisfied for a binary float x, since any such float has + nonnegative 5-valuation. For 0 > ndigits >= -22, x needs to be an + integral multiple of 5**-ndigits; we can check this using fmod. + For -22 > ndigits, there are no halfway cases: 5**23 takes 54 bits + to represent exactly, so any odd multiple of 0.5 * 10**n for n >= + 23 takes at least 54 bits of precision to represent exactly. + + Correction: a simple strategy for dealing with halfway cases is to + (for the halfway cases only) call _Py_dg_dtoa with an argument of + ndigits+1 instead of ndigits (thus doing an exact conversion to + decimal), round the resulting string manually, and then convert + back using _Py_dg_strtod. + */ + + /* nans, infinities and zeros should have already been dealt + with by the caller (in this case, builtin_round) */ + assert(Py_IS_FINITE(x) && x != 0.0); + + /* find 2-valuation val of x */ + m = frexp(x, &val); + while (m != floor(m)) { + m *= 2.0; + val--; + } + + /* determine whether this is a halfway case */ + if (val == -ndigits-1) { + if (ndigits >= 0) + halfway_case = 1; + else if (ndigits >= -FIVE_POW_LIMIT) { + double five_pow = 1.0; + int i; + for (i=0; i < -ndigits; i++) + five_pow *= 5.0; + halfway_case = fmod(x, five_pow) == 0.0; + } + else + halfway_case = 0; + } + else + halfway_case = 0; + + /* round to a decimal string; use an extra place for halfway case */ + buf = _Py_dg_dtoa(x, 3, ndigits+halfway_case, &decpt, &sign, &buf_end); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + buflen = buf_end - buf; + + /* in halfway case, do the round-half-away-from-zero manually */ + if (halfway_case) { + int i, carry; + /* sanity check: _Py_dg_dtoa should not have stripped + any zeros from the result: there should be exactly + ndigits+1 places following the decimal point, and + the last digit in the buffer should be a '5'.*/ + assert(buflen - decpt == ndigits+1); + assert(buf[buflen-1] == '5'); + + /* increment and shift right at the same time. */ + decpt += 1; + carry = 1; + for (i=buflen-1; i-- > 0;) { + carry += buf[i] - '0'; + buf[i+1] = carry % 10 + '0'; + carry /= 10; + } + buf[0] = carry + '0'; + } + + /* Get new buffer if shortbuf is too small. Space needed <= buf_end - + buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */ + if (buflen + 8 > mybuflen) { + mybuflen = buflen+8; + mybuf = (char *)PyMem_Malloc(mybuflen); + if (mybuf == NULL) { + PyErr_NoMemory(); + goto exit; + } + } + /* copy buf to mybuf, adding exponent, sign and leading 0 */ + PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""), + buf, decpt - (int)buflen); + + /* and convert the resulting string back to a double */ + errno = 0; + rounded = _Py_dg_strtod(mybuf, NULL); + if (errno == ERANGE && fabs(rounded) >= 1.) + PyErr_SetString(PyExc_OverflowError, + "rounded value too large to represent"); + else + result = PyFloat_FromDouble(rounded); + + /* done computing value; now clean up */ + if (mybuf != shortbuf) + PyMem_Free(mybuf); + exit: + _Py_dg_freedtoa(buf); + return result; +} + +#undef FIVE_POW_LIMIT + +#else /* PY_NO_SHORT_FLOAT_REPR */ + +/* fallback version, to be used when correctly rounded binary<->decimal + conversions aren't available */ + +PyObject * +_Py_double_round(double x, int ndigits) { + double pow1, pow2, y, z; + if (ndigits >= 0) { + if (ndigits > 22) { + /* pow1 and pow2 are each safe from overflow, but + pow1*pow2 ~= pow(10.0, ndigits) might overflow */ + pow1 = pow(10.0, (double)(ndigits-22)); + pow2 = 1e22; + } + else { + pow1 = pow(10.0, (double)ndigits); + pow2 = 1.0; + } + y = (x*pow1)*pow2; + /* if y overflows, then rounded value is exactly x */ + if (!Py_IS_FINITE(y)) + return PyFloat_FromDouble(x); + } + else { + pow1 = pow(10.0, (double)-ndigits); + pow2 = 1.0; /* unused; silences a gcc compiler warning */ + y = x / pow1; + } + + z = round(y); + if (fabs(y-z) == 0.5) + /* halfway between two integers; use round-away-from-zero */ + z = y + copysign(0.5, y); + + if (ndigits >= 0) + z = (z / pow2) / pow1; + else + z *= pow1; + + /* if computation resulted in overflow, raise OverflowError */ + if (!Py_IS_FINITE(z)) { + PyErr_SetString(PyExc_OverflowError, + "overflow occurred during round"); + return NULL; + } + + return PyFloat_FromDouble(z); +} + +#endif /* PY_NO_SHORT_FLOAT_REPR */ + static PyObject * float_float(PyObject *v) { Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Wed Nov 18 20:33:35 2009 @@ -8,6 +8,7 @@ #include "eval.h" #include +#include /* for DBL_MANT_DIG and friends */ #ifdef RISCOS #include "unixstuff.h" @@ -2120,29 +2121,47 @@ static PyObject * builtin_round(PyObject *self, PyObject *args, PyObject *kwds) { - double number; - double f; - int ndigits = 0; - int i; + double x; + PyObject *o_ndigits = NULL; + Py_ssize_t ndigits; static char *kwlist[] = {"number", "ndigits", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round", - kwlist, &number, &ndigits)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|O:round", + kwlist, &x, &o_ndigits)) return NULL; - f = 1.0; - i = abs(ndigits); - while (--i >= 0) - f = f*10.0; - if (ndigits < 0) - number /= f; - else - number *= f; - number = round(number); - if (ndigits < 0) - number *= f; + + /* nans, infinities and zeros round to themselves */ + if (!Py_IS_FINITE(x) || x == 0.0) + return PyFloat_FromDouble(x); + + if (o_ndigits == NULL) { + /* second argument defaults to 0 */ + ndigits = 0; + } + else { + /* interpret 2nd argument as a Py_ssize_t; clip on overflow */ + ndigits = PyNumber_AsSsize_t(o_ndigits, NULL); + if (ndigits == -1 && PyErr_Occurred()) + return NULL; + } + + /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x + always rounds to itself. For ndigits < NDIGITS_MIN, x always + rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */ +#define NDIGITS_MAX ((int)((DBL_MANT_DIG-DBL_MIN_EXP) * 0.30103)) +#define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103)) + if (ndigits > NDIGITS_MAX) + /* return x */ + return PyFloat_FromDouble(x); + else if (ndigits < NDIGITS_MIN) + /* return 0.0, but with sign of x */ + return PyFloat_FromDouble(0.0*x); else - number /= f; - return PyFloat_FromDouble(number); + /* finite x, and ndigits is not unreasonably large */ + /* _Py_double_round is defined in floatobject.c */ + return _Py_double_round(x, (int)ndigits); +#undef NDIGITS_MAX +#undef NDIGITS_MIN } PyDoc_STRVAR(round_doc, From python-checkins at python.org Wed Nov 18 20:34:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 19:34:33 -0000 Subject: [Python-checkins] r76374 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Wed Nov 18 20:34:33 2009 New Revision: 76374 Log: Blocked revisions 76373 via svnmerge ........ r76373 | mark.dickinson | 2009-11-18 19:33:35 +0000 (Wed, 18 Nov 2009) | 5 lines Issue #7117, continued: Change round implementation to use the correctly-rounded string <-> float conversions; this makes sure that the result of the round operation is correctly rounded, and hence displays nicely using the new float repr. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Nov 18 20:35:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 19:35:30 -0000 Subject: [Python-checkins] r76375 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Wed Nov 18 20:35:30 2009 New Revision: 76375 Log: Blocked revisions 76373 via svnmerge ........ r76373 | mark.dickinson | 2009-11-18 19:33:35 +0000 (Wed, 18 Nov 2009) | 5 lines Issue #7117, continued: Change round implementation to use the correctly-rounded string <-> float conversions; this makes sure that the result of the round operation is correctly rounded, and hence displays nicely using the new float repr. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Nov 18 20:39:15 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 19:39:15 -0000 Subject: [Python-checkins] r76376 - python/trunk/Doc/library/zipfile.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 20:39:14 2009 New Revision: 76376 Log: upcase Python Modified: python/trunk/Doc/library/zipfile.rst Modified: python/trunk/Doc/library/zipfile.rst ============================================================================== --- python/trunk/Doc/library/zipfile.rst (original) +++ python/trunk/Doc/library/zipfile.rst Wed Nov 18 20:39:14 2009 @@ -22,7 +22,7 @@ (that is ZIP files that are more than 4 GByte in size). It supports decryption of encrypted files in ZIP archives, but it currently cannot create an encrypted file. Decryption is extremely slow as it is -implemented in native python rather than C. +implemented in native Python rather than C. For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and :mod:`tarfile` modules. From python-checkins at python.org Wed Nov 18 21:05:15 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 18 Nov 2009 20:05:15 -0000 Subject: [Python-checkins] r76377 - python/trunk/Doc/library/string.rst Message-ID: Author: georg.brandl Date: Wed Nov 18 21:05:15 2009 New Revision: 76377 Log: Fix markup. Modified: python/trunk/Doc/library/string.rst Modified: python/trunk/Doc/library/string.rst ============================================================================== --- python/trunk/Doc/library/string.rst (original) +++ python/trunk/Doc/library/string.rst Wed Nov 18 21:05:15 2009 @@ -541,13 +541,12 @@ templates containing dangling delimiters, unmatched braces, or placeholders that are not valid Python identifiers. -:class:`Template` instances also provide one public data attribute: + :class:`Template` instances also provide one public data attribute: + .. attribute:: template -.. attribute:: string.template - - This is the object passed to the constructor's *template* argument. In general, - you shouldn't change it, but read-only access is not enforced. + This is the object passed to the constructor's *template* argument. In + general, you shouldn't change it, but read-only access is not enforced. Here is an example of how to use a Template: From python-checkins at python.org Wed Nov 18 21:13:27 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 18 Nov 2009 20:13:27 -0000 Subject: [Python-checkins] r76378 - python/branches/release26-maint/Objects/setobject.c Message-ID: Author: raymond.hettinger Date: Wed Nov 18 21:13:27 2009 New Revision: 76378 Log: Issue 7263: Fix set.intersection() docstring. Modified: python/branches/release26-maint/Objects/setobject.c Modified: python/branches/release26-maint/Objects/setobject.c ============================================================================== --- python/branches/release26-maint/Objects/setobject.c (original) +++ python/branches/release26-maint/Objects/setobject.c Wed Nov 18 21:13:27 2009 @@ -1339,9 +1339,9 @@ } PyDoc_STRVAR(intersection_doc, -"Return the intersection of two sets as a new set.\n\ +"Return the intersection of two or more sets as a new set.\n\ \n\ -(i.e. all elements that are in both sets.)"); +(i.e. elements that are common to all of the sets.)"); static PyObject * set_intersection_update(PySetObject *so, PyObject *other) From python-checkins at python.org Wed Nov 18 21:14:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 20:14:57 -0000 Subject: [Python-checkins] r76379 - python/trunk/Include/pyport.h Message-ID: Author: mark.dickinson Date: Wed Nov 18 21:14:57 2009 New Revision: 76379 Log: Enable short float repr\! Modified: python/trunk/Include/pyport.h Modified: python/trunk/Include/pyport.h ============================================================================== --- python/trunk/Include/pyport.h (original) +++ python/trunk/Include/pyport.h Wed Nov 18 21:14:57 2009 @@ -577,14 +577,6 @@ #define PY_NO_SHORT_FLOAT_REPR #endif -/* temporarily disable the new float repr while the pieces are being - assembled, unless PY_SHORT_FLOAT_REPR is defined. These 7 lines - should be gone by 01/01/10. If they're still here, please complain - to Mark Dickinson (dickinsm at gmail.com). */ -#ifndef PY_SHORT_FLOAT_REPR -#define PY_NO_SHORT_FLOAT_REPR -#endif - /* Py_DEPRECATED(version) * Declare a variable, type, or function deprecated. * Usage: From python-checkins at python.org Wed Nov 18 21:20:47 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 18 Nov 2009 20:20:47 -0000 Subject: [Python-checkins] r76380 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: Author: antoine.pitrou Date: Wed Nov 18 21:20:46 2009 New Revision: 76380 Log: Mention Giampolo R's new FTP TLS support in the what's new file Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Wed Nov 18 21:20:46 2009 @@ -724,6 +724,12 @@ :mod:`zipfile` now supports archiving empty directories and extracts them correctly. (Fixed by Kuba Wieczorek; :issue:`4710`.) +* The :mod:`ftplib` module gains the ability to establish secure FTP + connections using TLS encapsulation of authentication as well as + subsequent control and data transfers. This is provided by the new + :class:`ftplib.FTP_TLS` class. + (Contributed by Giampaolo Rodola', :issue:`2054`.) + .. ====================================================================== .. whole new modules get described in subsections here From python-checkins at python.org Wed Nov 18 21:24:54 2009 From: python-checkins at python.org (lars.gustaebel) Date: Wed, 18 Nov 2009 20:24:54 -0000 Subject: [Python-checkins] r76381 - in python/trunk: Lib/tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Wed Nov 18 21:24:54 2009 New Revision: 76381 Log: Issue #7341: Close the internal file object in the TarFile constructor in case of an error. Modified: python/trunk/Lib/tarfile.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/tarfile.py ============================================================================== --- python/trunk/Lib/tarfile.py (original) +++ python/trunk/Lib/tarfile.py Wed Nov 18 21:24:54 2009 @@ -1557,27 +1557,33 @@ self.inodes = {} # dictionary caching the inodes of # archive members already added - if self.mode == "r": - self.firstmember = None - self.firstmember = self.next() - - if self.mode == "a": - # Move to the end of the archive, - # before the first empty block. - self.firstmember = None - while True: - if self.next() is None: - if self.offset > 0: - self.fileobj.seek(- BLOCKSIZE, 1) - break - - if self.mode in "aw": - self._loaded = True - - if self.pax_headers: - buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) - self.fileobj.write(buf) - self.offset += len(buf) + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + self.firstmember = None + while True: + if self.next() is None: + if self.offset > 0: + self.fileobj.seek(- BLOCKSIZE, 1) + break + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise def _getposix(self): return self.format == USTAR_FORMAT Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 18 21:24:54 2009 @@ -440,6 +440,9 @@ Library ------- +- Issue #7341: Close the internal file object in the TarFile constructor in + case of an error. + - Issue #7293: distutils.test_msvc9compiler is fixed to work on any fresh Windows box. Help provided by David Bolen. From python-checkins at python.org Wed Nov 18 21:28:23 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 18 Nov 2009 20:28:23 -0000 Subject: [Python-checkins] r76382 - python/trunk/Objects/setobject.c Message-ID: Author: raymond.hettinger Date: Wed Nov 18 21:28:22 2009 New Revision: 76382 Log: Issue 7263: Fix set.intersection() docstring. Modified: python/trunk/Objects/setobject.c Modified: python/trunk/Objects/setobject.c ============================================================================== --- python/trunk/Objects/setobject.c (original) +++ python/trunk/Objects/setobject.c Wed Nov 18 21:28:22 2009 @@ -1339,9 +1339,9 @@ } PyDoc_STRVAR(intersection_doc, -"Return the intersection of two sets as a new set.\n\ +"Return the intersection of two or more sets as a new set.\n\ \n\ -(i.e. all elements that are in both sets.)"); +(i.e. elements that are common to all of the sets.)"); static PyObject * set_intersection_update(PySetObject *so, PyObject *other) From python-checkins at python.org Wed Nov 18 21:28:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 20:28:47 -0000 Subject: [Python-checkins] r76379 - svn:log Message-ID: Author: mark.dickinson Revision: 76379 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Enable short float repr\! \ No newline at end of file +Enable short float repr! \ No newline at end of file From python-checkins at python.org Wed Nov 18 21:29:25 2009 From: python-checkins at python.org (lars.gustaebel) Date: Wed, 18 Nov 2009 20:29:25 -0000 Subject: [Python-checkins] r76383 - in python/branches/py3k: Lib/tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Wed Nov 18 21:29:25 2009 New Revision: 76383 Log: Merged revisions 76381 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76381 | lars.gustaebel | 2009-11-18 21:24:54 +0100 (Wed, 18 Nov 2009) | 3 lines Issue #7341: Close the internal file object in the TarFile constructor in case of an error. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/tarfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Wed Nov 18 21:29:25 2009 @@ -1549,27 +1549,33 @@ self.inodes = {} # dictionary caching the inodes of # archive members already added - if self.mode == "r": - self.firstmember = None - self.firstmember = self.next() - - if self.mode == "a": - # Move to the end of the archive, - # before the first empty block. - self.firstmember = None - while True: - if self.next() is None: - if self.offset > 0: - self.fileobj.seek(self.fileobj.tell() - BLOCKSIZE) - break - - if self.mode in "aw": - self._loaded = True - - if self.pax_headers: - buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) - self.fileobj.write(buf) - self.offset += len(buf) + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + self.firstmember = None + while True: + if self.next() is None: + if self.offset > 0: + self.fileobj.seek(self.fileobj.tell() - BLOCKSIZE) + break + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise #-------------------------------------------------------------------------- # Below are the classmethods which act as alternate constructors to the Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Nov 18 21:29:25 2009 @@ -137,6 +137,9 @@ Library ------- +- Issue #7341: Close the internal file object in the TarFile constructor in + case of an error. + - Issue #7293: distutils.test_msvc9compiler is fixed to work on any fresh Windows box. Help provided by David Bolen. From python-checkins at python.org Wed Nov 18 21:31:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 20:31:08 -0000 Subject: [Python-checkins] r76384 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Wed Nov 18 21:31:07 2009 New Revision: 76384 Log: Blocked revisions 76379 via svnmerge ........ r76379 | mark.dickinson | 2009-11-18 20:14:57 +0000 (Wed, 18 Nov 2009) | 1 line Enable short float repr! ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Nov 18 21:32:09 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 18 Nov 2009 20:32:09 -0000 Subject: [Python-checkins] r76385 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Wed Nov 18 21:32:09 2009 New Revision: 76385 Log: Blocked revisions 76379 via svnmerge ........ r76379 | mark.dickinson | 2009-11-18 20:14:57 +0000 (Wed, 18 Nov 2009) | 1 line Enable short float repr! ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Nov 18 22:09:36 2009 From: python-checkins at python.org (lars.gustaebel) Date: Wed, 18 Nov 2009 21:09:36 -0000 Subject: [Python-checkins] r76386 - in python/branches/release26-maint: Lib/tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Wed Nov 18 22:09:35 2009 New Revision: 76386 Log: Merged revisions 76381 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76381 | lars.gustaebel | 2009-11-18 21:24:54 +0100 (Wed, 18 Nov 2009) | 3 lines Issue #7341: Close the internal file object in the TarFile constructor in case of an error. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/tarfile.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/tarfile.py ============================================================================== --- python/branches/release26-maint/Lib/tarfile.py (original) +++ python/branches/release26-maint/Lib/tarfile.py Wed Nov 18 22:09:35 2009 @@ -1565,27 +1565,33 @@ self.inodes = {} # dictionary caching the inodes of # archive members already added - if self.mode == "r": - self.firstmember = None - self.firstmember = self.next() - - if self.mode == "a": - # Move to the end of the archive, - # before the first empty block. - self.firstmember = None - while True: - if self.next() is None: - if self.offset > 0: - self.fileobj.seek(- BLOCKSIZE, 1) - break - - if self.mode in "aw": - self._loaded = True - - if self.pax_headers: - buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) - self.fileobj.write(buf) - self.offset += len(buf) + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + self.firstmember = None + while True: + if self.next() is None: + if self.offset > 0: + self.fileobj.seek(- BLOCKSIZE, 1) + break + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise def _getposix(self): return self.format == USTAR_FORMAT Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Nov 18 22:09:35 2009 @@ -26,6 +26,9 @@ Library ------- +- Issue #7341: Close the internal file object in the TarFile constructor in + case of an error. + - Issue #7328: pydoc no longer corrupts sys.path when run with the '-m' switch - Issue #7318: multiprocessing now uses a timeout when it fails to establish From python-checkins at python.org Wed Nov 18 22:11:28 2009 From: python-checkins at python.org (lars.gustaebel) Date: Wed, 18 Nov 2009 21:11:28 -0000 Subject: [Python-checkins] r76387 - in python/branches/release31-maint: Lib/tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Wed Nov 18 22:11:27 2009 New Revision: 76387 Log: Merged revisions 76383 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76383 | lars.gustaebel | 2009-11-18 21:29:25 +0100 (Wed, 18 Nov 2009) | 10 lines Merged revisions 76381 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76381 | lars.gustaebel | 2009-11-18 21:24:54 +0100 (Wed, 18 Nov 2009) | 3 lines Issue #7341: Close the internal file object in the TarFile constructor in case of an error. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/tarfile.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/tarfile.py ============================================================================== --- python/branches/release31-maint/Lib/tarfile.py (original) +++ python/branches/release31-maint/Lib/tarfile.py Wed Nov 18 22:11:27 2009 @@ -1554,27 +1554,33 @@ self.inodes = {} # dictionary caching the inodes of # archive members already added - if self.mode == "r": - self.firstmember = None - self.firstmember = self.next() - - if self.mode == "a": - # Move to the end of the archive, - # before the first empty block. - self.firstmember = None - while True: - if self.next() is None: - if self.offset > 0: - self.fileobj.seek(self.fileobj.tell() - BLOCKSIZE) - break - - if self.mode in "aw": - self._loaded = True - - if self.pax_headers: - buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) - self.fileobj.write(buf) - self.offset += len(buf) + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + self.firstmember = None + while True: + if self.next() is None: + if self.offset > 0: + self.fileobj.seek(self.fileobj.tell() - BLOCKSIZE) + break + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise #-------------------------------------------------------------------------- # Below are the classmethods which act as alternate constructors to the Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Wed Nov 18 22:11:27 2009 @@ -46,6 +46,9 @@ Library ------- +- Issue #7341: Close the internal file object in the TarFile constructor in + case of an error. + - Issue #7293: distutils.test_msvc9compiler is fixed to work on any fresh Windows box. Help provided by David Bolen. From solipsis at pitrou.net Thu Nov 19 00:46:37 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 19 Nov 2009 00:46:37 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76383): sum=-17 Message-ID: <20091118234637.A452D17758@ns6635.ovh.net> py3k results for svn r76383 (hg cset 04ba3d43c407) -------------------------------------------------- test_urllib leaked [4, 6, 2] references, sum=12 test_zipimport_support leaked [0, 0, -29] references, sum=-29 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogkXBzHD', '-x', 'test_httpservers'] From python-checkins at python.org Thu Nov 19 01:01:54 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 00:01:54 -0000 Subject: [Python-checkins] r76388 - python/branches/release31-maint/Objects/setobject.c Message-ID: Author: raymond.hettinger Date: Thu Nov 19 01:01:54 2009 New Revision: 76388 Log: Issue 7263: Fix set.intersection() docstring. Modified: python/branches/release31-maint/Objects/setobject.c Modified: python/branches/release31-maint/Objects/setobject.c ============================================================================== --- python/branches/release31-maint/Objects/setobject.c (original) +++ python/branches/release31-maint/Objects/setobject.c Thu Nov 19 01:01:54 2009 @@ -1343,9 +1343,9 @@ } PyDoc_STRVAR(intersection_doc, -"Return the intersection of two sets as a new set.\n\ +"Return the intersection of two or more sets as a new set.\n\ \n\ -(i.e. all elements that are in both sets.)"); +(i.e. elements that are common to all of the sets.)"); static PyObject * set_intersection_update(PySetObject *so, PyObject *other) From python-checkins at python.org Thu Nov 19 02:02:57 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 01:02:57 -0000 Subject: [Python-checkins] r76389 - in python/branches/release31-maint: Lib/pprint.py Lib/test/test_pprint.py Misc/NEWS Message-ID: Author: raymond.hettinger Date: Thu Nov 19 02:02:56 2009 New Revision: 76389 Log: Issue 3976: fix pprint for sets, frozensets, and dicts containing unorderable types. Modified: python/branches/release31-maint/Lib/pprint.py python/branches/release31-maint/Lib/test/test_pprint.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/pprint.py ============================================================================== --- python/branches/release31-maint/Lib/pprint.py (original) +++ python/branches/release31-maint/Lib/pprint.py Thu Nov 19 02:02:56 2009 @@ -70,6 +70,32 @@ """Determine if object requires a recursive representation.""" return _safe_repr(object, {}, None, 0)[2] +class _safe_key: + """Helper function for key functions when sorting unorderable objects. + + The wrapped-object will fallback to an Py2.x style comparison for + unorderable types (sorting first comparing the type name and then by + the obj ids). Does not work recursively, so dict.items() must have + _safe_key applied to both the key and the value. + + """ + + __slots__ = ['obj'] + + def __init__(self, obj): + self.obj = obj + + def __lt__(self, other): + rv = self.obj.__lt__(other.obj) + if rv is NotImplemented: + rv = (str(type(self.obj)), id(self.obj)) < \ + (str(type(other.obj)), id(other.obj)) + return rv + +def _safe_tuple(t): + "Helper function for comparing 2-tuples" + return _safe_key(t[0]), _safe_key(t[1]) + class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None): """Handle pretty printing operations onto a stream using a set of @@ -145,7 +171,7 @@ if length: context[objid] = 1 indent = indent + self._indent_per_level - items = sorted(object.items()) + items = sorted(object.items(), key=_safe_tuple) key, ent = items[0] rep = self._repr(key, context, level) write(rep) @@ -178,14 +204,14 @@ return write('{') endchar = '}' - object = sorted(object) + object = sorted(object, key=_safe_key) elif issubclass(typ, frozenset): if not length: write('frozenset()') return write('frozenset({') endchar = '})' - object = sorted(object) + object = sorted(object, key=_safe_key) indent += 10 else: write('(') @@ -267,14 +293,7 @@ append = components.append level += 1 saferepr = _safe_repr - items = object.items() - try: - items = sorted(items) - except TypeError: - def sortkey(item): - key, value = item - return str(type(key)), key, value - items = sorted(items, key=sortkey) + items = sorted(object.items(), key=_safe_tuple) for k, v in items: krepr, kreadable, krecur = saferepr(k, context, maxlevels, level) vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level) Modified: python/branches/release31-maint/Lib/test/test_pprint.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_pprint.py (original) +++ python/branches/release31-maint/Lib/test/test_pprint.py Thu Nov 19 02:02:56 2009 @@ -2,6 +2,7 @@ import test.support import unittest import test.test_set +import random # list, tuple and dict subclasses that do or don't overwrite __repr__ class list2(list): @@ -25,6 +26,10 @@ def __repr__(self): return dict.__repr__(self) +class Unorderable: + def __repr__(self): + return str(id(self)) + class QueryTestCase(unittest.TestCase): def setUp(self): @@ -407,6 +412,20 @@ self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict) self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list) + def test_sort_unorderable_values(self): + # Issue 3976: sorted pprints fail for unorderable values. + n = 20 + keys = [Unorderable() for i in range(n)] + random.shuffle(keys) + skeys = sorted(keys, key=id) + clean = lambda s: s.replace(' ', '').replace('\n','') + + self.assertEqual(clean(pprint.pformat(set(keys))), + '{' + ','.join(map(repr, skeys)) + '}') + self.assertEqual(clean(pprint.pformat(frozenset(keys))), + 'frozenset({' + ','.join(map(repr, skeys)) + '})') + self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))), + '{' + ','.join('%r:None' % k for k in skeys) + '}') class DottedPrettyPrinter(pprint.PrettyPrinter): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 19 02:02:56 2009 @@ -46,6 +46,9 @@ Library ------- +- Issue #3976: pprint for sets, frozensets, and dicts now succeed when + they contain unorderable types. + - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. From python-checkins at python.org Thu Nov 19 02:07:06 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 01:07:06 -0000 Subject: [Python-checkins] r76390 - in python/branches/py3k/Lib: pprint.py test/test_pprint.py Message-ID: Author: raymond.hettinger Date: Thu Nov 19 02:07:05 2009 New Revision: 76390 Log: Issue 3976: fix pprint for sets, frozensets, and dicts containing unorderable types. Modified: python/branches/py3k/Lib/pprint.py python/branches/py3k/Lib/test/test_pprint.py Modified: python/branches/py3k/Lib/pprint.py ============================================================================== --- python/branches/py3k/Lib/pprint.py (original) +++ python/branches/py3k/Lib/pprint.py Thu Nov 19 02:07:05 2009 @@ -70,6 +70,32 @@ """Determine if object requires a recursive representation.""" return _safe_repr(object, {}, None, 0)[2] +class _safe_key: + """Helper function for key functions when sorting unorderable objects. + + The wrapped-object will fallback to an Py2.x style comparison for + unorderable types (sorting first comparing the type name and then by + the obj ids). Does not work recursively, so dict.items() must have + _safe_key applied to both the key and the value. + + """ + + __slots__ = ['obj'] + + def __init__(self, obj): + self.obj = obj + + def __lt__(self, other): + rv = self.obj.__lt__(other.obj) + if rv is NotImplemented: + rv = (str(type(self.obj)), id(self.obj)) < \ + (str(type(other.obj)), id(other.obj)) + return rv + +def _safe_tuple(t): + "Helper function for comparing 2-tuples" + return _safe_key(t[0]), _safe_key(t[1]) + class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None): """Handle pretty printing operations onto a stream using a set of @@ -145,7 +171,7 @@ if length: context[objid] = 1 indent = indent + self._indent_per_level - items = sorted(object.items()) + items = sorted(object.items(), key=_safe_tuple) key, ent = items[0] rep = self._repr(key, context, level) write(rep) @@ -178,14 +204,14 @@ return write('{') endchar = '}' - object = sorted(object) + object = sorted(object, key=_safe_key) elif issubclass(typ, frozenset): if not length: write('frozenset()') return write('frozenset({') endchar = '})' - object = sorted(object) + object = sorted(object, key=_safe_key) indent += 10 else: write('(') @@ -267,14 +293,7 @@ append = components.append level += 1 saferepr = _safe_repr - items = object.items() - try: - items = sorted(items) - except TypeError: - def sortkey(item): - key, value = item - return str(type(key)), key, value - items = sorted(items, key=sortkey) + items = sorted(object.items(), key=_safe_tuple) for k, v in items: krepr, kreadable, krecur = saferepr(k, context, maxlevels, level) vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level) Modified: python/branches/py3k/Lib/test/test_pprint.py ============================================================================== --- python/branches/py3k/Lib/test/test_pprint.py (original) +++ python/branches/py3k/Lib/test/test_pprint.py Thu Nov 19 02:07:05 2009 @@ -2,6 +2,7 @@ import test.support import unittest import test.test_set +import random # list, tuple and dict subclasses that do or don't overwrite __repr__ class list2(list): @@ -25,6 +26,10 @@ def __repr__(self): return dict.__repr__(self) +class Unorderable: + def __repr__(self): + return str(id(self)) + class QueryTestCase(unittest.TestCase): def setUp(self): @@ -407,6 +412,20 @@ self.assertEqual(pprint.pformat(nested_dict, depth=1), lv1_dict) self.assertEqual(pprint.pformat(nested_list, depth=1), lv1_list) + def test_sort_unorderable_values(self): + # Issue 3976: sorted pprints fail for unorderable values. + n = 20 + keys = [Unorderable() for i in range(n)] + random.shuffle(keys) + skeys = sorted(keys, key=id) + clean = lambda s: s.replace(' ', '').replace('\n','') + + self.assertEqual(clean(pprint.pformat(set(keys))), + '{' + ','.join(map(repr, skeys)) + '}') + self.assertEqual(clean(pprint.pformat(frozenset(keys))), + 'frozenset({' + ','.join(map(repr, skeys)) + '})') + self.assertEqual(clean(pprint.pformat(dict.fromkeys(keys))), + '{' + ','.join('%r:None' % k for k in skeys) + '}') class DottedPrettyPrinter(pprint.PrettyPrinter): From python-checkins at python.org Thu Nov 19 02:20:08 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 01:20:08 -0000 Subject: [Python-checkins] r76391 - in python/branches/py3k: Doc/library/itertools.rst Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Nov 19 02:20:07 2009 New Revision: 76391 Log: Fix docstrings for itertools combinatoric functions. Modified: python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Modules/itertoolsmodule.c Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Thu Nov 19 02:20:07 2009 @@ -65,8 +65,8 @@ ============================================== ==================== ============================================================= :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements -:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements -:func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements +:func:`combinations` p, r r-length tuples, in sorted order, no repeated elements +:func:`combinations_with_replacement` p, r r-length tuples, in sorted order, with repeated elements | ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Thu Nov 19 02:20:07 2009 @@ -2017,7 +2017,7 @@ } PyDoc_STRVAR(combinations_doc, -"combinations(iterable[, r]) --> combinations object\n\ +"combinations(iterable, r) --> combinations object\n\ \n\ Return successive r-length combinations of elements in the iterable.\n\n\ combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)"); @@ -2262,7 +2262,7 @@ } PyDoc_STRVAR(cwr_doc, -"combinations_with_replacement(iterable[, r]) --> combinations_with_replacement object\n\ +"combinations_with_replacement(iterable, r) --> combinations_with_replacement object\n\ \n\ Return successive r-length combinations of elements in the iterable\n\ allowing individual elements to have successive repeats.\n\ @@ -3494,8 +3494,8 @@ Combinatoric generators:\n\ product(p, q, ... [repeat=1]) --> cartesian product\n\ permutations(p[, r])\n\ -combinations(p[, r])\n\ -combinations_with_replacement(p[, r])\n\ +combinations(p, r)\n\ +combinations_with_replacement(p, r)\n\ "); From python-checkins at python.org Thu Nov 19 02:22:04 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 01:22:04 -0000 Subject: [Python-checkins] r76392 - in python/trunk: Doc/library/itertools.rst Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Nov 19 02:22:04 2009 New Revision: 76392 Log: Fix docstrings for itertools combinatoric functions. Modified: python/trunk/Doc/library/itertools.rst python/trunk/Modules/itertoolsmodule.c Modified: python/trunk/Doc/library/itertools.rst ============================================================================== --- python/trunk/Doc/library/itertools.rst (original) +++ python/trunk/Doc/library/itertools.rst Thu Nov 19 02:22:04 2009 @@ -71,8 +71,8 @@ ============================================== ==================== ============================================================= :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements -:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements -:func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements +:func:`combinations` p, r r-length tuples, in sorted order, no repeated elements +:func:`combinations_with_replacement` p, r r-length tuples, in sorted order, with repeated elements | ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Thu Nov 19 02:22:04 2009 @@ -2196,7 +2196,7 @@ } PyDoc_STRVAR(combinations_doc, -"combinations(iterable[, r]) --> combinations object\n\ +"combinations(iterable, r) --> combinations object\n\ \n\ Return successive r-length combinations of elements in the iterable.\n\n\ combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)"); @@ -2441,7 +2441,7 @@ } PyDoc_STRVAR(cwr_doc, -"combinations_with_replacement(iterable[, r]) --> combinations_with_replacement object\n\ +"combinations_with_replacement(iterable, r) --> combinations_with_replacement object\n\ \n\ Return successive r-length combinations of elements in the iterable\n\ allowing individual elements to have successive repeats.\n\ @@ -4018,8 +4018,8 @@ Combinatoric generators:\n\ product(p, q, ... [repeat=1]) --> cartesian product\n\ permutations(p[, r])\n\ -combinations(p[, r])\n\ -combinations_with_replacement(p[, r])\n\ +combinations(p, r)\n\ +combinations_with_replacement(p, r)\n\ "); From python-checkins at python.org Thu Nov 19 02:23:42 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 01:23:42 -0000 Subject: [Python-checkins] r76393 - in python/branches/release31-maint: Doc/library/itertools.rst Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Nov 19 02:23:41 2009 New Revision: 76393 Log: Fix docstrings for itertools combinatoric functions. Modified: python/branches/release31-maint/Doc/library/itertools.rst python/branches/release31-maint/Modules/itertoolsmodule.c Modified: python/branches/release31-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release31-maint/Doc/library/itertools.rst (original) +++ python/branches/release31-maint/Doc/library/itertools.rst Thu Nov 19 02:23:41 2009 @@ -65,8 +65,8 @@ ============================================== ==================== ============================================================= :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements -:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements -:func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements +:func:`combinations` p, r r-length tuples, in sorted order, no repeated elements +:func:`combinations_with_replacement` p, r r-length tuples, in sorted order, with repeated elements | ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` Modified: python/branches/release31-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release31-maint/Modules/itertoolsmodule.c Thu Nov 19 02:23:41 2009 @@ -2017,7 +2017,7 @@ } PyDoc_STRVAR(combinations_doc, -"combinations(iterable[, r]) --> combinations object\n\ +"combinations(iterable, r) --> combinations object\n\ \n\ Return successive r-length combinations of elements in the iterable.\n\n\ combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)"); @@ -2262,7 +2262,7 @@ } PyDoc_STRVAR(cwr_doc, -"combinations_with_replacement(iterable[, r]) --> combinations_with_replacement object\n\ +"combinations_with_replacement(iterable, r) --> combinations_with_replacement object\n\ \n\ Return successive r-length combinations of elements in the iterable\n\ allowing individual elements to have successive repeats.\n\ @@ -3494,8 +3494,8 @@ Combinatoric generators:\n\ product(p, q, ... [repeat=1]) --> cartesian product\n\ permutations(p[, r])\n\ -combinations(p[, r])\n\ -combinations_with_replacement(p[, r])\n\ +combinations(p, r)\n\ +combinations_with_replacement(p, r)\n\ "); From python-checkins at python.org Thu Nov 19 02:26:24 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 19 Nov 2009 01:26:24 -0000 Subject: [Python-checkins] r76394 - in python/branches/release26-maint: Doc/library/itertools.rst Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Thu Nov 19 02:26:23 2009 New Revision: 76394 Log: Fix docstrings for itertools combinatoric functions. Modified: python/branches/release26-maint/Doc/library/itertools.rst python/branches/release26-maint/Modules/itertoolsmodule.c Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Thu Nov 19 02:26:23 2009 @@ -70,7 +70,7 @@ ============================================== ==================== ============================================================= :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements -:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements +:func:`combinations` p, r r-length tuples, in sorted order, no repeated elements | ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` Modified: python/branches/release26-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release26-maint/Modules/itertoolsmodule.c Thu Nov 19 02:26:23 2009 @@ -2194,7 +2194,7 @@ } PyDoc_STRVAR(combinations_doc, -"combinations(iterable[, r]) --> combinations object\n\ +"combinations(iterable, r) --> combinations object\n\ \n\ Return successive r-length combinations of elements in the iterable.\n\n\ combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)"); @@ -3542,6 +3542,11 @@ takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n\ dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n\ groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n\ +\n\ +Combinatoric generators:\n\ +product(p, q, ... [repeat=1]) --> cartesian product\n\ +permutations(p[, r])\n\ +combinations(p, r)\n\ "); From python-checkins at python.org Thu Nov 19 04:00:03 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 03:00:03 -0000 Subject: [Python-checkins] r76395 - in python/trunk: Lib/test/test_weakref.py Misc/NEWS Objects/weakrefobject.c Message-ID: Author: benjamin.peterson Date: Thu Nov 19 04:00:02 2009 New Revision: 76395 Log: #5037 proxy __unicode__ correctly Modified: python/trunk/Lib/test/test_weakref.py python/trunk/Misc/NEWS python/trunk/Objects/weakrefobject.c Modified: python/trunk/Lib/test/test_weakref.py ============================================================================== --- python/trunk/Lib/test/test_weakref.py (original) +++ python/trunk/Lib/test/test_weakref.py Thu Nov 19 04:00:02 2009 @@ -188,6 +188,17 @@ self.assertEqual(L3[:5], p3[:5]) self.assertEqual(L3[2:5], p3[2:5]) + def test_proxy_unicode(self): + # See bug 5037 + class C(object): + def __str__(self): + return "string" + def __unicode__(self): + return u"unicode" + instance = C() + self.assertTrue("__unicode__" in dir(weakref.proxy(instance))) + self.assertEqual(unicode(weakref.proxy(instance)), u"unicode") + def test_proxy_index(self): class C: def __index__(self): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Nov 19 04:00:02 2009 @@ -440,6 +440,9 @@ Library ------- +- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ + instead of __str__. + - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. Modified: python/trunk/Objects/weakrefobject.c ============================================================================== --- python/trunk/Objects/weakrefobject.c (original) +++ python/trunk/Objects/weakrefobject.c Thu Nov 19 04:00:02 2009 @@ -433,6 +433,13 @@ return generic(proxy, v, w); \ } +#define WRAP_METHOD(method, special) \ + static PyObject * \ + method(PyObject *proxy) { \ + UNWRAP(proxy); \ + return PyObject_CallMethod(proxy, special, ""); \ + } + /* direct slots */ @@ -593,6 +600,15 @@ } +WRAP_METHOD(proxy_unicode, "__unicode__"); + + +static PyMethodDef proxy_methods[] = { + {"__unicode__", (PyCFunction)proxy_unicode, METH_NOARGS}, + {NULL, NULL} +}; + + static PyNumberMethods proxy_as_number = { proxy_add, /*nb_add*/ proxy_sub, /*nb_subtract*/ @@ -684,6 +700,7 @@ 0, /* tp_weaklistoffset */ (getiterfunc)proxy_iter, /* tp_iter */ (iternextfunc)proxy_iternext, /* tp_iternext */ + proxy_methods, /* tp_methods */ }; From python-checkins at python.org Thu Nov 19 04:08:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 03:08:32 -0000 Subject: [Python-checkins] r76396 - in python/branches/py3k: Lib/test/test_weakref.py Misc/NEWS Objects/weakrefobject.c Message-ID: Author: benjamin.peterson Date: Thu Nov 19 04:08:32 2009 New Revision: 76396 Log: fix __bytes__ handling here in py3x Merged revisions 76395 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76395 | benjamin.peterson | 2009-11-18 21:00:02 -0600 (Wed, 18 Nov 2009) | 1 line #5037 proxy __unicode__ correctly ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_weakref.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/weakrefobject.c Modified: python/branches/py3k/Lib/test/test_weakref.py ============================================================================== --- python/branches/py3k/Lib/test/test_weakref.py (original) +++ python/branches/py3k/Lib/test/test_weakref.py Thu Nov 19 04:08:32 2009 @@ -183,6 +183,17 @@ self.assertEqual(L3[:5], p3[:5]) self.assertEqual(L3[2:5], p3[2:5]) + def test_proxy_unicode(self): + # See bug 5037 + class C(object): + def __str__(self): + return "string" + def __bytes__(self): + return b"bytes" + instance = C() + self.assertTrue("__bytes__" in dir(weakref.proxy(instance))) + self.assertEqual(bytes(weakref.proxy(instance)), b"bytes") + def test_proxy_index(self): class C: def __index__(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 19 04:08:32 2009 @@ -137,6 +137,9 @@ Library ------- +- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ + instead of __str__. + - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. Modified: python/branches/py3k/Objects/weakrefobject.c ============================================================================== --- python/branches/py3k/Objects/weakrefobject.c (original) +++ python/branches/py3k/Objects/weakrefobject.c Thu Nov 19 04:08:32 2009 @@ -435,6 +435,13 @@ return generic(proxy, v, w); \ } +#define WRAP_METHOD(method, special) \ + static PyObject * \ + method(PyObject *proxy) { \ + UNWRAP(proxy); \ + return PyObject_CallMethod(proxy, special, ""); \ + } + /* direct slots */ @@ -576,6 +583,15 @@ } +WRAP_METHOD(proxy_bytes, "__bytes__"); + + +static PyMethodDef proxy_methods[] = { + {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS}, + {NULL, NULL} +}; + + static PyNumberMethods proxy_as_number = { proxy_add, /*nb_add*/ proxy_sub, /*nb_subtract*/ @@ -661,6 +677,7 @@ 0, /* tp_weaklistoffset */ (getiterfunc)proxy_iter, /* tp_iter */ (iternextfunc)proxy_iternext, /* tp_iternext */ + proxy_methods, /* tp_methods */ }; From python-checkins at python.org Thu Nov 19 04:10:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 03:10:36 -0000 Subject: [Python-checkins] r76397 - in python/branches/release31-maint: Lib/test/test_weakref.py Misc/NEWS Objects/weakrefobject.c Message-ID: Author: benjamin.peterson Date: Thu Nov 19 04:10:36 2009 New Revision: 76397 Log: Merged revisions 76396 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76396 | benjamin.peterson | 2009-11-18 21:08:32 -0600 (Wed, 18 Nov 2009) | 10 lines fix __bytes__ handling here in py3x Merged revisions 76395 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76395 | benjamin.peterson | 2009-11-18 21:00:02 -0600 (Wed, 18 Nov 2009) | 1 line #5037 proxy __unicode__ correctly ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_weakref.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Objects/weakrefobject.c Modified: python/branches/release31-maint/Lib/test/test_weakref.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_weakref.py (original) +++ python/branches/release31-maint/Lib/test/test_weakref.py Thu Nov 19 04:10:36 2009 @@ -183,6 +183,17 @@ self.assertEqual(L3[:5], p3[:5]) self.assertEqual(L3[2:5], p3[2:5]) + def test_proxy_unicode(self): + # See bug 5037 + class C(object): + def __str__(self): + return "string" + def __bytes__(self): + return b"bytes" + instance = C() + self.assertTrue("__bytes__" in dir(weakref.proxy(instance))) + self.assertEqual(bytes(weakref.proxy(instance)), b"bytes") + def test_proxy_index(self): class C: def __index__(self): Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 19 04:10:36 2009 @@ -49,6 +49,9 @@ - Issue #3976: pprint for sets, frozensets, and dicts now succeed when they contain unorderable types. +- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ + instead of __str__. + - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. Modified: python/branches/release31-maint/Objects/weakrefobject.c ============================================================================== --- python/branches/release31-maint/Objects/weakrefobject.c (original) +++ python/branches/release31-maint/Objects/weakrefobject.c Thu Nov 19 04:10:36 2009 @@ -435,6 +435,13 @@ return generic(proxy, v, w); \ } +#define WRAP_METHOD(method, special) \ + static PyObject * \ + method(PyObject *proxy) { \ + UNWRAP(proxy); \ + return PyObject_CallMethod(proxy, special, ""); \ + } + /* direct slots */ @@ -576,6 +583,15 @@ } +WRAP_METHOD(proxy_bytes, "__bytes__"); + + +static PyMethodDef proxy_methods[] = { + {"__bytes__", (PyCFunction)proxy_bytes, METH_NOARGS}, + {NULL, NULL} +}; + + static PyNumberMethods proxy_as_number = { proxy_add, /*nb_add*/ proxy_sub, /*nb_subtract*/ @@ -661,6 +677,7 @@ 0, /* tp_weaklistoffset */ (getiterfunc)proxy_iter, /* tp_iter */ (iternextfunc)proxy_iternext, /* tp_iternext */ + proxy_methods, /* tp_methods */ }; From python-checkins at python.org Thu Nov 19 04:11:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 03:11:10 -0000 Subject: [Python-checkins] r76398 - in python/branches/release26-maint: Lib/test/test_weakref.py Misc/NEWS Objects/weakrefobject.c Message-ID: Author: benjamin.peterson Date: Thu Nov 19 04:11:09 2009 New Revision: 76398 Log: Merged revisions 76395 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76395 | benjamin.peterson | 2009-11-18 21:00:02 -0600 (Wed, 18 Nov 2009) | 1 line #5037 proxy __unicode__ correctly ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_weakref.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/weakrefobject.c Modified: python/branches/release26-maint/Lib/test/test_weakref.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_weakref.py (original) +++ python/branches/release26-maint/Lib/test/test_weakref.py Thu Nov 19 04:11:09 2009 @@ -188,6 +188,17 @@ self.assertEqual(L3[:5], p3[:5]) self.assertEqual(L3[2:5], p3[2:5]) + def test_proxy_unicode(self): + # See bug 5037 + class C(object): + def __str__(self): + return "string" + def __unicode__(self): + return u"unicode" + instance = C() + self.assertTrue("__unicode__" in dir(weakref.proxy(instance))) + self.assertEqual(unicode(weakref.proxy(instance)), u"unicode") + def test_proxy_index(self): class C: def __index__(self): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Nov 19 04:11:09 2009 @@ -251,6 +251,9 @@ Library ------- +- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ + instead of __str__. + - Issue #6894: Fixed the issue urllib2 doesn't respect "no_proxy" environment - Issue #6790: Make it possible again to pass an `array.array` to Modified: python/branches/release26-maint/Objects/weakrefobject.c ============================================================================== --- python/branches/release26-maint/Objects/weakrefobject.c (original) +++ python/branches/release26-maint/Objects/weakrefobject.c Thu Nov 19 04:11:09 2009 @@ -433,6 +433,13 @@ return generic(proxy, v, w); \ } +#define WRAP_METHOD(method, special) \ + static PyObject * \ + method(PyObject *proxy) { \ + UNWRAP(proxy); \ + return PyObject_CallMethod(proxy, special, ""); \ + } + /* direct slots */ @@ -593,6 +600,15 @@ } +WRAP_METHOD(proxy_unicode, "__unicode__"); + + +static PyMethodDef proxy_methods[] = { + {"__unicode__", (PyCFunction)proxy_unicode, METH_NOARGS}, + {NULL, NULL} +}; + + static PyNumberMethods proxy_as_number = { proxy_add, /*nb_add*/ proxy_sub, /*nb_subtract*/ @@ -684,6 +700,7 @@ 0, /* tp_weaklistoffset */ (getiterfunc)proxy_iter, /* tp_iter */ (iternextfunc)proxy_iternext, /* tp_iternext */ + proxy_methods, /* tp_methods */ }; From python-checkins at python.org Thu Nov 19 06:33:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 19 Nov 2009 05:33:17 -0000 Subject: [Python-checkins] r76399 - in python/trunk: Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Thu Nov 19 06:33:16 2009 New Revision: 76399 Log: dragfullwindows can have value 2 Modified: python/trunk/Lib/distutils/tests/test_msvc9compiler.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/trunk/Lib/distutils/tests/test_msvc9compiler.py Thu Nov 19 06:33:16 2009 @@ -46,7 +46,7 @@ # windows registeries versions. path = r'Control Panel\Desktop' v = Reg.get_value(path, u'dragfullwindows') - self.assertTrue(v in (u'0', u'1')) + self.assertTrue(v in (u'0', u'1', u'2')) import _winreg HKCU = _winreg.HKEY_CURRENT_USER Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Nov 19 06:33:16 2009 @@ -440,6 +440,9 @@ Library ------- +- Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can + be 2. + - Issue #5037: Proxy the __unicode__ special method instead to __unicode__ instead of __str__. From python-checkins at python.org Thu Nov 19 06:34:14 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 19 Nov 2009 05:34:14 -0000 Subject: [Python-checkins] r76400 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Thu Nov 19 06:34:14 2009 New Revision: 76400 Log: Blocked revisions 76399 via svnmerge ........ r76399 | tarek.ziade | 2009-11-19 06:33:16 +0100 (Thu, 19 Nov 2009) | 1 line dragfullwindows can have value 2 ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Nov 19 06:39:00 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 19 Nov 2009 05:39:00 -0000 Subject: [Python-checkins] r76401 - in python/branches/py3k: Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Thu Nov 19 06:39:00 2009 New Revision: 76401 Log: Merged revisions 76399 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76399 | tarek.ziade | 2009-11-19 06:33:16 +0100 (Thu, 19 Nov 2009) | 1 line dragfullwindows can have value 2 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Thu Nov 19 06:39:00 2009 @@ -46,7 +46,7 @@ # windows registeries versions. path = r'Control Panel\Desktop' v = Reg.get_value(path, 'dragfullwindows') - self.assertTrue(v in ('0', '1')) + self.assertTrue(v in ('0', '1', '2')) import winreg HKCU = winreg.HKEY_CURRENT_USER Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 19 06:39:00 2009 @@ -137,6 +137,9 @@ Library ------- +- Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can + be 2. + - Issue #5037: Proxy the __unicode__ special method instead to __unicode__ instead of __str__. From python-checkins at python.org Thu Nov 19 06:41:34 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 19 Nov 2009 05:41:34 -0000 Subject: [Python-checkins] r76402 - in python/branches/release31-maint: Lib/distutils/tests/test_msvc9compiler.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Thu Nov 19 06:41:34 2009 New Revision: 76402 Log: Merged revisions 76401 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76401 | tarek.ziade | 2009-11-19 06:39:00 +0100 (Thu, 19 Nov 2009) | 9 lines Merged revisions 76399 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76399 | tarek.ziade | 2009-11-19 06:33:16 +0100 (Thu, 19 Nov 2009) | 1 line dragfullwindows can have value 2 ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py Thu Nov 19 06:41:34 2009 @@ -46,7 +46,7 @@ # windows registeries versions. path = r'Control Panel\Desktop' v = Reg.get_value(path, 'dragfullwindows') - self.assertTrue(v in ('0', '1')) + self.assertTrue(v in ('0', '1', '2')) import winreg HKCU = winreg.HKEY_CURRENT_USER Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 19 06:41:34 2009 @@ -46,6 +46,9 @@ Library ------- +- Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can + be 2. + - Issue #3976: pprint for sets, frozensets, and dicts now succeed when they contain unorderable types. From ncoghlan at gmail.com Thu Nov 19 13:10:49 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 19 Nov 2009 22:10:49 +1000 Subject: [Python-checkins] r76396 - in python/branches/py3k: Lib/test/test_weakref.py Misc/NEWS Objects/weakrefobject.c In-Reply-To: <4b04ba80.1567f10a.2b0e.54d4SMTPIN_ADDED@mx.google.com> References: <4b04ba80.1567f10a.2b0e.54d4SMTPIN_ADDED@mx.google.com> Message-ID: <4B0535C9.2010404@gmail.com> benjamin.peterson wrote: > Modified: python/branches/py3k/Misc/NEWS > ============================================================================== > --- python/branches/py3k/Misc/NEWS (original) > +++ python/branches/py3k/Misc/NEWS Thu Nov 19 04:08:32 2009 > @@ -137,6 +137,9 @@ > Library > ------- > > +- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ > + instead of __str__. > + Need a different NEWS message for the Py3k branches. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From ncoghlan at gmail.com Thu Nov 19 13:07:56 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 19 Nov 2009 22:07:56 +1000 Subject: [Python-checkins] Daily py3k reference leaks (r76383): sum=-17 In-Reply-To: <20091118234637.A452D17758@ns6635.ovh.net> References: <20091118234637.A452D17758@ns6635.ovh.net> Message-ID: <4B05351C.7010203@gmail.com> solipsis at pitrou.net wrote: > test_zipimport_support leaked [0, 0, -29] references, sum=-29 o.O That's a little special... If it happens again, I'll have a closer look to see if I might have caused it with the regrtest updates to restore the zipimport directory cache. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From solipsis at pitrou.net Thu Nov 19 13:20:11 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Thu, 19 Nov 2009 13:20:11 +0100 Subject: [Python-checkins] Daily py3k reference leaks (r76383): sum=-17 In-Reply-To: <4B05351C.7010203@gmail.com> References: <20091118234637.A452D17758@ns6635.ovh.net> <4B05351C.7010203@gmail.com> Message-ID: <1258633211.4597.5.camel@localhost> Le jeudi 19 novembre 2009 ? 22:07 +1000, Nick Coghlan a ?crit : > solipsis at pitrou.net wrote: > > test_zipimport_support leaked [0, 0, -29] references, sum=-29 > > o.O > > That's a little special... > > If it happens again, I'll have a closer look to see if I might have > caused it with the regrtest updates to restore the zipimport directory > cache. No, it happens quite often (which means you should be able to reproduce it) and is older than that. You're welcome to take a look though ;) From python-checkins at python.org Thu Nov 19 17:25:22 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 16:25:22 -0000 Subject: [Python-checkins] r76403 - in python/trunk: Misc/NEWS configure configure.in Message-ID: Author: ronald.oussoren Date: Thu Nov 19 17:25:21 2009 New Revision: 76403 Log: Fix for issue #7085 On MacOSX 10.6 the CoreFoundation framework must be initialized on the main thread, the constructor function in that framework will cause an SIGABRT when it is called on any other thread. Because a number of extension link (indirectly) to CoreFoundation and the Python core itself didn't the interpreter crashed when importing some extensions, such as _locale, on a secondary thread. This fix ensures that Python is linked to CoreFoundation on OSX, which results in the CoreFoundation constructor being called when Python is loaded. This does not require code changes. Modified: python/trunk/Misc/NEWS python/trunk/configure python/trunk/configure.in Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Nov 19 17:25:21 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7085: Fix crash when importing some extensions in a thread + on MacOSX 10.6. + - Issue #7117: Backport round implementation from Python 3.x. round now uses David Gay's correctly-rounded string <-> double conversions (when available), and so produces correctly rounded results. There Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Nov 19 17:25:21 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76300 . +# From configure.in Revision: 76308 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -3865,7 +3865,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f conftest* +rm -f -r conftest* @@ -5413,7 +5413,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -5434,7 +5434,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -6532,7 +6532,7 @@ fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -7062,7 +7062,7 @@ else ac_cv_type_uid_t=no fi -rm -f conftest* +rm -f -r conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15722,7 +15722,7 @@ else unistd_defines_pthreads=no fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -17336,7 +17336,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f conftest* +rm -f -r conftest* ;; kame) @@ -17359,7 +17359,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-glibc) @@ -17380,7 +17380,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-inet6) @@ -17418,7 +17418,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; v6d) @@ -17441,7 +17441,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -f -r conftest* ;; zeta) @@ -17463,7 +17463,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; esac @@ -25744,7 +25744,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -25763,7 +25763,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -26033,7 +26033,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -27111,6 +27111,11 @@ fi +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + { echo "$as_me:$LINENO: checking for %zd printf() format support" >&5 echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6; } Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Nov 19 17:25:21 2009 @@ -3999,6 +3999,11 @@ [Define to printf format modifier for long long type]) fi +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl AC_TRY_RUN([ From python-checkins at python.org Thu Nov 19 17:37:34 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 16:37:34 -0000 Subject: [Python-checkins] r76404 - in python/branches/release26-maint: Misc/NEWS configure configure.in Message-ID: Author: ronald.oussoren Date: Thu Nov 19 17:37:33 2009 New Revision: 76404 Log: Merged revisions 76403 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76403 | ronald.oussoren | 2009-11-19 17:25:21 +0100 (Thu, 19 Nov 2009) | 14 lines Fix for issue #7085 On MacOSX 10.6 the CoreFoundation framework must be initialized on the main thread, the constructor function in that framework will cause an SIGABRT when it is called on any other thread. Because a number of extension link (indirectly) to CoreFoundation and the Python core itself didn't the interpreter crashed when importing some extensions, such as _locale, on a secondary thread. This fix ensures that Python is linked to CoreFoundation on OSX, which results in the CoreFoundation constructor being called when Python is loaded. This does not require code changes. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/configure python/branches/release26-maint/configure.in Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Nov 19 17:37:33 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7085: Fix crash when importing some extensions in a thread + on MacOSX 10.6. + - Issue #7070: Fix round bug for large odd integer arguments. - Issue #7078: Set struct.__doc__ from _struct.__doc__. Modified: python/branches/release26-maint/configure ============================================================================== --- python/branches/release26-maint/configure (original) +++ python/branches/release26-maint/configure Thu Nov 19 17:37:33 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 75132 . +# From configure.in Revision: 75747 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.6. # @@ -3855,7 +3855,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f conftest* +rm -f -r conftest* @@ -5394,7 +5394,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -5415,7 +5415,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -6513,7 +6513,7 @@ fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -7043,7 +7043,7 @@ else ac_cv_type_uid_t=no fi -rm -f conftest* +rm -f -r conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -14163,7 +14163,7 @@ else unistd_defines_pthreads=no fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -15777,7 +15777,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f conftest* +rm -f -r conftest* ;; kame) @@ -15800,7 +15800,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-glibc) @@ -15821,7 +15821,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-inet6) @@ -15859,7 +15859,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; v6d) @@ -15882,7 +15882,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -f -r conftest* ;; zeta) @@ -15904,7 +15904,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; esac @@ -23497,7 +23497,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -23516,7 +23516,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -23786,7 +23786,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -24938,6 +24938,13 @@ THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" done +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + + + SRCDIRS="Parser Grammar Objects Python Modules Mac" { echo "$as_me:$LINENO: checking for build directories" >&5 Modified: python/branches/release26-maint/configure.in ============================================================================== --- python/branches/release26-maint/configure.in (original) +++ python/branches/release26-maint/configure.in Thu Nov 19 17:37:33 2009 @@ -3841,6 +3841,13 @@ THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" done +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + + + AC_SUBST(SRCDIRS) SRCDIRS="Parser Grammar Objects Python Modules Mac" AC_MSG_CHECKING(for build directories) From python-checkins at python.org Thu Nov 19 18:15:31 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 17:15:31 -0000 Subject: [Python-checkins] r76405 - in python/branches/py3k: Misc/NEWS configure configure.in Message-ID: Author: ronald.oussoren Date: Thu Nov 19 18:15:31 2009 New Revision: 76405 Log: Merged revisions 76403 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76403 | ronald.oussoren | 2009-11-19 17:25:21 +0100 (Thu, 19 Nov 2009) | 14 lines Fix for issue #7085 On MacOSX 10.6 the CoreFoundation framework must be initialized on the main thread, the constructor function in that framework will cause an SIGABRT when it is called on any other thread. Because a number of extension link (indirectly) to CoreFoundation and the Python core itself didn't the interpreter crashed when importing some extensions, such as _locale, on a secondary thread. This fix ensures that Python is linked to CoreFoundation on OSX, which results in the CoreFoundation constructor being called when Python is loaded. This does not require code changes. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 19 18:15:31 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7085: Fix crash when importing some extensions in a thread + on MacOSX 10.6. + - Issue #1757126: Fix the cyrillic-asian alias for the ptcp154 encoding. - Issue #6970: Remove redundant calls when comparing objects that don't Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Nov 19 18:15:31 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76301 . +# From configure.in Revision: 76328 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -3800,7 +3800,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f conftest* +rm -f -r conftest* @@ -5338,7 +5338,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -5359,7 +5359,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -6457,7 +6457,7 @@ fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -6987,7 +6987,7 @@ else ac_cv_type_uid_t=no fi -rm -f conftest* +rm -f -r conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15529,7 +15529,7 @@ else unistd_defines_pthreads=no fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -16827,7 +16827,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f conftest* +rm -f -r conftest* ;; kame) @@ -16850,7 +16850,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-glibc) @@ -16871,7 +16871,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-inet6) @@ -16909,7 +16909,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; v6d) @@ -16932,7 +16932,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -f -r conftest* ;; zeta) @@ -16954,7 +16954,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; esac @@ -25044,7 +25044,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -25063,7 +25063,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -25333,7 +25333,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -26411,6 +26411,10 @@ fi +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi { echo "$as_me:$LINENO: checking for %zd printf() format support" >&5 echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6; } Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Nov 19 18:15:31 2009 @@ -3853,6 +3853,10 @@ [Define to printf format modifier for long long type]) fi +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi AC_MSG_CHECKING(for %zd printf() format support) AC_CACHE_VAL(ac_cv_have_size_t_format, From python-checkins at python.org Thu Nov 19 18:30:06 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 17:30:06 -0000 Subject: [Python-checkins] r76406 - in python/branches/release31-maint: Misc/NEWS configure configure.in Message-ID: Author: ronald.oussoren Date: Thu Nov 19 18:30:05 2009 New Revision: 76406 Log: Merged revisions 76405 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76405 | ronald.oussoren | 2009-11-19 18:15:31 +0100 (Thu, 19 Nov 2009) | 21 lines Merged revisions 76403 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76403 | ronald.oussoren | 2009-11-19 17:25:21 +0100 (Thu, 19 Nov 2009) | 14 lines Fix for issue #7085 On MacOSX 10.6 the CoreFoundation framework must be initialized on the main thread, the constructor function in that framework will cause an SIGABRT when it is called on any other thread. Because a number of extension link (indirectly) to CoreFoundation and the Python core itself didn't the interpreter crashed when importing some extensions, such as _locale, on a secondary thread. This fix ensures that Python is linked to CoreFoundation on OSX, which results in the CoreFoundation constructor being called when Python is loaded. This does not require code changes. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/configure python/branches/release31-maint/configure.in Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 19 18:30:05 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7085: Fix crash when importing some extensions in a thread + on MacOSX 10.6. + - Issue #7298: fixes for range and reversed(range(...)). Iteration over range(a, b, c) incorrectly gave an empty iterator when a, b and c fit in C long but the length of the range did not. Also fix Modified: python/branches/release31-maint/configure ============================================================================== --- python/branches/release31-maint/configure (original) +++ python/branches/release31-maint/configure Thu Nov 19 18:30:05 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 74980 . +# From configure.in Revision: 75727 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -3802,7 +3802,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f conftest* +rm -f -r conftest* @@ -5350,7 +5350,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -5371,7 +5371,7 @@ else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -6469,7 +6469,7 @@ fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -6999,7 +6999,7 @@ else ac_cv_type_uid_t=no fi -rm -f conftest* +rm -f -r conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -14409,7 +14409,7 @@ else unistd_defines_pthreads=no fi -rm -f conftest* +rm -f -r conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -15877,7 +15877,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f conftest* +rm -f -r conftest* ;; kame) @@ -15900,7 +15900,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-glibc) @@ -15921,7 +15921,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -f -r conftest* ;; linux-inet6) @@ -15959,7 +15959,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; v6d) @@ -15982,7 +15982,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -f -r conftest* ;; zeta) @@ -16004,7 +16004,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -f -r conftest* ;; esac @@ -23989,7 +23989,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -24008,7 +24008,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -24278,7 +24278,7 @@ _ACEOF fi -rm -f conftest* +rm -f -r conftest* fi @@ -25513,6 +25513,12 @@ fi +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + + Modified: python/branches/release31-maint/configure.in ============================================================================== --- python/branches/release31-maint/configure.in (original) +++ python/branches/release31-maint/configure.in Thu Nov 19 18:30:05 2009 @@ -3939,6 +3939,12 @@ fi], [AC_MSG_RESULT(no)]) +if test $ac_sys_system = Darwin +then + LIBS="$LIBS -framework CoreFoundation" +fi + + AC_SUBST(THREADHEADERS) From python-checkins at python.org Thu Nov 19 18:42:51 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 17:42:51 -0000 Subject: [Python-checkins] r76407 - python/trunk/Mac/BuildScript/scripts/postflight.patch-profile Message-ID: Author: ronald.oussoren Date: Thu Nov 19 18:42:51 2009 New Revision: 76407 Log: Don't use the '==' operator with test, that's an unportable bash-ism. (Issue 7179) Modified: python/trunk/Mac/BuildScript/scripts/postflight.patch-profile Modified: python/trunk/Mac/BuildScript/scripts/postflight.patch-profile ============================================================================== --- python/trunk/Mac/BuildScript/scripts/postflight.patch-profile (original) +++ python/trunk/Mac/BuildScript/scripts/postflight.patch-profile Thu Nov 19 18:42:51 2009 @@ -36,10 +36,10 @@ # Now ensure that our bin directory is on $P and before /usr/bin at that for elem in `echo $P | tr ':' ' '` do - if [ "${elem}" == "${PYTHON_ROOT}/bin" ]; then + if [ "${elem}" = "${PYTHON_ROOT}/bin" ]; then echo "All right, you're a python lover already" exit 0 - elif [ "${elem}" == "/usr/bin" ]; then + elif [ "${elem}" = "/usr/bin" ]; then break fi done From python-checkins at python.org Thu Nov 19 18:43:53 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 17:43:53 -0000 Subject: [Python-checkins] r76408 - in python/branches/release26-maint: Mac/BuildScript/scripts/postflight.patch-profile Message-ID: Author: ronald.oussoren Date: Thu Nov 19 18:43:53 2009 New Revision: 76408 Log: Merged revisions 76407 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76407 | ronald.oussoren | 2009-11-19 18:42:51 +0100 (Thu, 19 Nov 2009) | 4 lines Don't use the '==' operator with test, that's an unportable bash-ism. (Issue 7179) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Mac/BuildScript/scripts/postflight.patch-profile Modified: python/branches/release26-maint/Mac/BuildScript/scripts/postflight.patch-profile ============================================================================== --- python/branches/release26-maint/Mac/BuildScript/scripts/postflight.patch-profile (original) +++ python/branches/release26-maint/Mac/BuildScript/scripts/postflight.patch-profile Thu Nov 19 18:43:53 2009 @@ -36,10 +36,10 @@ # Now ensure that our bin directory is on $P and before /usr/bin at that for elem in `echo $P | tr ':' ' '` do - if [ "${elem}" == "${PYTHON_ROOT}/bin" ]; then + if [ "${elem}" = "${PYTHON_ROOT}/bin" ]; then echo "All right, you're a python lover already" exit 0 - elif [ "${elem}" == "/usr/bin" ]; then + elif [ "${elem}" = "/usr/bin" ]; then break fi done From python-checkins at python.org Thu Nov 19 18:44:53 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 17:44:53 -0000 Subject: [Python-checkins] r76409 - in python/branches/py3k: Mac/BuildScript/scripts/postflight.patch-profile Message-ID: Author: ronald.oussoren Date: Thu Nov 19 18:44:52 2009 New Revision: 76409 Log: Merged revisions 76407 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76407 | ronald.oussoren | 2009-11-19 18:42:51 +0100 (Thu, 19 Nov 2009) | 4 lines Don't use the '==' operator with test, that's an unportable bash-ism. (Issue 7179) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Mac/BuildScript/scripts/postflight.patch-profile Modified: python/branches/py3k/Mac/BuildScript/scripts/postflight.patch-profile ============================================================================== --- python/branches/py3k/Mac/BuildScript/scripts/postflight.patch-profile (original) +++ python/branches/py3k/Mac/BuildScript/scripts/postflight.patch-profile Thu Nov 19 18:44:52 2009 @@ -36,10 +36,10 @@ # Now ensure that our bin directory is on $P and before /usr/bin at that for elem in `echo $P | tr ':' ' '` do - if [ "${elem}" == "${PYTHON_ROOT}/bin" ]; then + if [ "${elem}" = "${PYTHON_ROOT}/bin" ]; then echo "All right, you're a python lover already" exit 0 - elif [ "${elem}" == "/usr/bin" ]; then + elif [ "${elem}" = "/usr/bin" ]; then break fi done From python-checkins at python.org Thu Nov 19 18:45:30 2009 From: python-checkins at python.org (ronald.oussoren) Date: Thu, 19 Nov 2009 17:45:30 -0000 Subject: [Python-checkins] r76410 - in python/branches/release31-maint: Mac/BuildScript/scripts/postflight.patch-profile Message-ID: Author: ronald.oussoren Date: Thu Nov 19 18:45:30 2009 New Revision: 76410 Log: Merged revisions 76409 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76409 | ronald.oussoren | 2009-11-19 18:44:52 +0100 (Thu, 19 Nov 2009) | 11 lines Merged revisions 76407 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76407 | ronald.oussoren | 2009-11-19 18:42:51 +0100 (Thu, 19 Nov 2009) | 4 lines Don't use the '==' operator with test, that's an unportable bash-ism. (Issue 7179) ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Mac/BuildScript/scripts/postflight.patch-profile Modified: python/branches/release31-maint/Mac/BuildScript/scripts/postflight.patch-profile ============================================================================== --- python/branches/release31-maint/Mac/BuildScript/scripts/postflight.patch-profile (original) +++ python/branches/release31-maint/Mac/BuildScript/scripts/postflight.patch-profile Thu Nov 19 18:45:30 2009 @@ -36,10 +36,10 @@ # Now ensure that our bin directory is on $P and before /usr/bin at that for elem in `echo $P | tr ':' ' '` do - if [ "${elem}" == "${PYTHON_ROOT}/bin" ]; then + if [ "${elem}" = "${PYTHON_ROOT}/bin" ]; then echo "All right, you're a python lover already" exit 0 - elif [ "${elem}" == "/usr/bin" ]; then + elif [ "${elem}" = "/usr/bin" ]; then break fi done From python-checkins at python.org Thu Nov 19 19:41:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 19 Nov 2009 18:41:49 -0000 Subject: [Python-checkins] r76411 - python/trunk/Misc/NEWS Message-ID: Author: mark.dickinson Date: Thu Nov 19 19:41:49 2009 New Revision: 76411 Log: Misc/NEWS entries for issue 7117. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Nov 19 19:41:49 2009 @@ -15,11 +15,40 @@ - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. +- Issue #7117: repr(x) for a float x returns a result based on the + shortest decimal string that's guaranteed to round back to x under + correct rounding (with round-half-to-even rounding mode). + Previously it gave a string based on rounding x to 17 decimal digits. + repr(x) for a complex number behaves similarly. On platforms where + the correctly-rounded strtod and dtoa code is not supported (see below), + repr is unchanged. + +- Issue #7117: On almost all platforms: float-to-string and + string-to-float conversions within Python are now correctly rounded. + Places these conversions occur include: str for floats and complex + numbers; the float and complex constructors; old-style and new-style + numeric formatting; serialization and deserialization of floats and + complex numbers using marshal, pickle and json; parsing of float and + imaginary literals in Python code; Decimal-to-float conversion. + + The conversions use a Python-adapted version of David Gay's + well-known dtoa.c, providing correctly-rounded strtod and dtoa C + functions. This code is supported on Windows, and on Unix-like + platforms using gcc, icc or suncc as the C compiler. There may be a + small number of platforms on which correct operation of this code + cannot be guaranteed, so the code is not used: notably, this applies + to platforms where the C double format is not IEEE 754 binary64, and + to platforms on x86 hardware where the x87 FPU is set to 64-bit + precision and Python's configure script is unable to determine how + to change the FPU precision. On these platforms conversions use the + platform strtod and dtoa, as before. + - Issue #7117: Backport round implementation from Python 3.x. round - now uses David Gay's correctly-rounded string <-> double conversions - (when available), and so produces correctly rounded results. There - are two related small changes: (1) round now accepts any class with - an __index__ method for its second argument (but no longer accepts + now uses the correctly-rounded string <-> float conversions + described above (when available), and so produces correctly rounded + results that will display nicely under the float repr. There are + two related small changes: (1) round now accepts any class with an + __index__ method for its second argument (but no longer accepts floats for the second argument), and (2) an excessively large second integer argument (e.g., round(1.234, 10**100)) no longer raises an exception. From python-checkins at python.org Thu Nov 19 19:42:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 19 Nov 2009 18:42:19 -0000 Subject: [Python-checkins] r76412 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Thu Nov 19 19:42:18 2009 New Revision: 76412 Log: Blocked revisions 76411 via svnmerge ........ r76411 | mark.dickinson | 2009-11-19 18:41:49 +0000 (Thu, 19 Nov 2009) | 1 line Misc/NEWS entries for issue 7117. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Nov 19 19:43:03 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 19 Nov 2009 18:43:03 -0000 Subject: [Python-checkins] r76413 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Thu Nov 19 19:43:03 2009 New Revision: 76413 Log: Blocked revisions 76411 via svnmerge ........ r76411 | mark.dickinson | 2009-11-19 18:41:49 +0000 (Thu, 19 Nov 2009) | 1 line Misc/NEWS entries for issue 7117. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Nov 19 22:22:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 21:22:27 -0000 Subject: [Python-checkins] r76414 - python/branches/py3k/Misc/NEWS Message-ID: Author: benjamin.peterson Date: Thu Nov 19 22:22:27 2009 New Revision: 76414 Log: fix message for py3 Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 19 22:22:27 2009 @@ -143,8 +143,8 @@ - Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can be 2. -- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ - instead of __str__. +- Issue #5037: Proxy the __bytes__ special method instead to __bytes__ instead + of __str__. - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. From python-checkins at python.org Thu Nov 19 22:26:17 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 21:26:17 -0000 Subject: [Python-checkins] r76415 - in python/branches/release31-maint: Misc/NEWS Message-ID: Author: benjamin.peterson Date: Thu Nov 19 22:26:17 2009 New Revision: 76415 Log: Merged revisions 76414 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76414 | benjamin.peterson | 2009-11-19 15:22:27 -0600 (Thu, 19 Nov 2009) | 1 line fix message for py3 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Thu Nov 19 22:26:17 2009 @@ -55,8 +55,8 @@ - Issue #3976: pprint for sets, frozensets, and dicts now succeed when they contain unorderable types. -- Issue #5037: Proxy the __unicode__ special method instead to __unicode__ - instead of __str__. +- Issue #5037: Proxy the __bytes__ special method instead to __bytes__ instead + of __str__. - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. From python-checkins at python.org Thu Nov 19 23:54:57 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 22:54:57 -0000 Subject: [Python-checkins] r76416 - in python/trunk: Lib/test/test_py3kwarn.py Lib/test/test_syntax.py Python/ast.c Message-ID: Author: benjamin.peterson Date: Thu Nov 19 23:54:57 2009 New Revision: 76416 Log: improve several corner cases related with argument names in parenthesis - Fix #7362: give a good error message for parenthesized arguments with defaults. - Add a py3k warning for any parenthesized arguments since those are not allowed in Py3. This warning is not given in tuple unpacking, since that incurs the tuple unpacking warning. Modified: python/trunk/Lib/test/test_py3kwarn.py python/trunk/Lib/test/test_syntax.py python/trunk/Python/ast.c Modified: python/trunk/Lib/test/test_py3kwarn.py ============================================================================== --- python/trunk/Lib/test/test_py3kwarn.py (original) +++ python/trunk/Lib/test/test_py3kwarn.py Thu Nov 19 23:54:57 2009 @@ -30,6 +30,18 @@ exec "`2`" in {} self.assertWarning(None, w, expected) + def test_paren_arg_names(self): + expected = 'parenthesized argument names are invalid in 3.x' + def check(s): + exec s in {} + self.assertWarning(None, w, expected) + with check_warnings() as w: + check("def f((x)): pass") + check("def f((((x))), (y)): pass") + check("def f((x), (((y))), m=32): pass") + # Something like def f((a, (b))): pass will raise the tuple + # unpacking warning. + def test_forbidden_names(self): # So we don't screw up our globals def safe_exec(expr): Modified: python/trunk/Lib/test/test_syntax.py ============================================================================== --- python/trunk/Lib/test/test_syntax.py (original) +++ python/trunk/Lib/test/test_syntax.py Thu Nov 19 23:54:57 2009 @@ -493,10 +493,14 @@ self.fail("SyntaxError is not a %s" % subclass.__name__) mo = re.search(errtext, str(err)) if mo is None: - self.fail("SyntaxError did not contain '%r'" % (errtext,)) + self.fail("%s did not contain '%r'" % (err, errtext,)) else: self.fail("compile() did not raise SyntaxError") + def test_paren_arg_with_default(self): + self._check_error("def f((x)=23): pass", + "parenthesized arg with default") + def test_assign_call(self): self._check_error("f() = 1", "assign") Modified: python/trunk/Python/ast.c ============================================================================== --- python/trunk/Python/ast.c (original) +++ python/trunk/Python/ast.c Thu Nov 19 23:54:57 2009 @@ -692,7 +692,8 @@ while (i < NCH(n)) { ch = CHILD(n, i); switch (TYPE(ch)) { - case fpdef: + case fpdef: { + int complex_args = 0, parenthesized = 0; handle_fpdef: /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is anything other than EQUAL or a comma? */ @@ -707,6 +708,12 @@ found_default = 1; } else if (found_default) { + /* def f((x)=4): pass should raise an error. + def f((x, (y))): pass will just incur the tuple unpacking warning. */ + if (parenthesized && !complex_args) { + ast_error(n, "parenthesized arg with default"); + goto error; + } ast_error(n, "non-default argument follows default argument"); goto error; @@ -719,6 +726,7 @@ if (Py_Py3kWarningFlag && !ast_warn(c, ch, "tuple parameter unpacking has been removed in 3.x")) goto error; + complex_args = 1; asdl_seq_SET(args, k++, compiler_complex_args(c, ch)); if (!asdl_seq_GET(args, k-1)) goto error; @@ -726,6 +734,7 @@ /* def foo((x)): setup for checking NAME below. */ /* Loop because there can be many parens and tuple unpacking mixed in. */ + parenthesized = 1; ch = CHILD(ch, 0); assert(TYPE(ch) == fpdef); goto handle_fpdef; @@ -747,7 +756,13 @@ } i += 2; /* the name and the comma */ + if (parenthesized && Py_Py3kWarningFlag && + !ast_warn(c, ch, "parenthesized argument names " + "are invalid in 3.x")) + goto error; + break; + } case STAR: if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1)))) goto error; From python-checkins at python.org Thu Nov 19 23:58:01 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 22:58:01 -0000 Subject: [Python-checkins] r76417 - python/trunk/Misc/NEWS Message-ID: Author: benjamin.peterson Date: Thu Nov 19 23:58:01 2009 New Revision: 76417 Log: add news notes for r76416 Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Nov 19 23:58:01 2009 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Add Py3k warnings for parameter names in parenthesis. + +- Issue #7362: Give a propery error message for def f((x)=3): pass. + - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. From python-checkins at python.org Fri Nov 20 00:00:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 23:00:13 -0000 Subject: [Python-checkins] r76418 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Fri Nov 20 00:00:13 2009 New Revision: 76418 Log: Blocked revisions 76416-76417 via svnmerge ........ r76416 | benjamin.peterson | 2009-11-19 16:54:57 -0600 (Thu, 19 Nov 2009) | 10 lines improve several corner cases related with argument names in parenthesis - Fix #7362: give a good error message for parenthesized arguments with defaults. - Add a py3k warning for any parenthesized arguments since those are not allowed in Py3. This warning is not given in tuple unpacking, since that incurs the tuple unpacking warning. ........ r76417 | benjamin.peterson | 2009-11-19 16:58:01 -0600 (Thu, 19 Nov 2009) | 1 line add news notes for r76416 ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Nov 20 00:01:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 23:01:36 -0000 Subject: [Python-checkins] r76419 - in python/branches/release26-maint: Lib/test/test_py3kwarn.py Lib/test/test_syntax.py Misc/NEWS Python/ast.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 00:01:36 2009 New Revision: 76419 Log: Merged revisions 76416-76417 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76416 | benjamin.peterson | 2009-11-19 16:54:57 -0600 (Thu, 19 Nov 2009) | 10 lines improve several corner cases related with argument names in parenthesis - Fix #7362: give a good error message for parenthesized arguments with defaults. - Add a py3k warning for any parenthesized arguments since those are not allowed in Py3. This warning is not given in tuple unpacking, since that incurs the tuple unpacking warning. ........ r76417 | benjamin.peterson | 2009-11-19 16:58:01 -0600 (Thu, 19 Nov 2009) | 1 line add news notes for r76416 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_py3kwarn.py python/branches/release26-maint/Lib/test/test_syntax.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Python/ast.c Modified: python/branches/release26-maint/Lib/test/test_py3kwarn.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_py3kwarn.py (original) +++ python/branches/release26-maint/Lib/test/test_py3kwarn.py Fri Nov 20 00:01:36 2009 @@ -31,6 +31,18 @@ exec "`2`" in {} self.assertWarning(None, w, expected) + def test_paren_arg_names(self): + expected = 'parenthesized argument names are invalid in 3.x' + def check(s): + exec s in {} + self.assertWarning(None, w, expected) + with check_warnings() as w: + check("def f((x)): pass") + check("def f((((x))), (y)): pass") + check("def f((x), (((y))), m=32): pass") + # Something like def f((a, (b))): pass will raise the tuple + # unpacking warning. + def test_bool_assign(self): # So we don't screw up our globals def safe_exec(expr): Modified: python/branches/release26-maint/Lib/test/test_syntax.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_syntax.py (original) +++ python/branches/release26-maint/Lib/test/test_syntax.py Fri Nov 20 00:01:36 2009 @@ -447,10 +447,14 @@ self.fail("SyntaxError is not a %s" % subclass.__name__) mo = re.search(errtext, str(err)) if mo is None: - self.fail("SyntaxError did not contain '%r'" % (errtext,)) + self.fail("%s did not contain '%r'" % (err, errtext,)) else: self.fail("compile() did not raise SyntaxError") + def test_paren_arg_with_default(self): + self._check_error("def f((x)=23): pass", + "parenthesized arg with default") + def test_assign_call(self): self._check_error("f() = 1", "assign") Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Nov 20 00:01:36 2009 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Add Py3k warnings for parameter names in parenthesis. + +- Issue #7362: Give a propery error message for def f((x)=3): pass. + - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. Modified: python/branches/release26-maint/Python/ast.c ============================================================================== --- python/branches/release26-maint/Python/ast.c (original) +++ python/branches/release26-maint/Python/ast.c Fri Nov 20 00:01:36 2009 @@ -682,7 +682,8 @@ while (i < NCH(n)) { ch = CHILD(n, i); switch (TYPE(ch)) { - case fpdef: + case fpdef: { + int complex_args = 0, parenthesized = 0; handle_fpdef: /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is anything other than EQUAL or a comma? */ @@ -697,6 +698,12 @@ found_default = 1; } else if (found_default) { + /* def f((x)=4): pass should raise an error. + def f((x, (y))): pass will just incur the tuple unpacking warning. */ + if (parenthesized && !complex_args) { + ast_error(n, "parenthesized arg with default"); + goto error; + } ast_error(n, "non-default argument follows default argument"); goto error; @@ -709,6 +716,7 @@ if (Py_Py3kWarningFlag && !ast_warn(c, ch, "tuple parameter unpacking has been removed in 3.x")) goto error; + complex_args = 1; asdl_seq_SET(args, k++, compiler_complex_args(c, ch)); if (!asdl_seq_GET(args, k-1)) goto error; @@ -716,6 +724,7 @@ /* def foo((x)): setup for checking NAME below. */ /* Loop because there can be many parens and tuple unpacking mixed in. */ + parenthesized = 1; ch = CHILD(ch, 0); assert(TYPE(ch) == fpdef); goto handle_fpdef; @@ -737,7 +746,13 @@ } i += 2; /* the name and the comma */ + if (parenthesized && Py_Py3kWarningFlag && + !ast_warn(c, ch, "parenthesized argument names " + "are invalid in 3.x")) + goto error; + break; + } case STAR: if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1)))) goto error; From g.brandl at gmx.net Fri Nov 20 00:14:02 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Fri, 20 Nov 2009 00:14:02 +0100 Subject: [Python-checkins] r76417 - python/trunk/Misc/NEWS In-Reply-To: <39973.3345643201$1258671605@news.gmane.org> References: <39973.3345643201$1258671605@news.gmane.org> Message-ID: benjamin.peterson schrieb: > Author: benjamin.peterson > Date: Thu Nov 19 23:58:01 2009 > New Revision: 76417 > > Log: > add news notes for r76416 > > Modified: > python/trunk/Misc/NEWS > > Modified: python/trunk/Misc/NEWS > ============================================================================== > --- python/trunk/Misc/NEWS (original) > +++ python/trunk/Misc/NEWS Thu Nov 19 23:58:01 2009 > @@ -12,6 +12,10 @@ > Core and Builtins > ----------------- > > +- Add Py3k warnings for parameter names in parenthesis. > + > +- Issue #7362: Give a propery error message for def f((x)=3): pass. Should be "proper". Georg From nnorwitz at gmail.com Fri Nov 20 00:18:19 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 19 Nov 2009 18:18:19 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091119231819.GA23076@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 0, 26] references, sum=26 Less important issues: ---------------------- From python-checkins at python.org Fri Nov 20 00:19:29 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 23:19:29 -0000 Subject: [Python-checkins] r76420 - python/trunk/Misc/NEWS Message-ID: Author: benjamin.peterson Date: Fri Nov 20 00:19:29 2009 New Revision: 76420 Log: spelling Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 20 00:19:29 2009 @@ -14,7 +14,7 @@ - Add Py3k warnings for parameter names in parenthesis. -- Issue #7362: Give a propery error message for def f((x)=3): pass. +- Issue #7362: Give a proper error message for def f((x)=3): pass. - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. From python-checkins at python.org Fri Nov 20 00:23:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 23:23:56 -0000 Subject: [Python-checkins] r76421 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Fri Nov 20 00:23:56 2009 New Revision: 76421 Log: Blocked revisions 76420 via svnmerge ........ r76420 | benjamin.peterson | 2009-11-19 17:19:29 -0600 (Thu, 19 Nov 2009) | 1 line spelling ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Nov 20 00:25:14 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 19 Nov 2009 23:25:14 -0000 Subject: [Python-checkins] r76422 - in python/branches/release26-maint: Misc/NEWS Message-ID: Author: benjamin.peterson Date: Fri Nov 20 00:25:14 2009 New Revision: 76422 Log: Merged revisions 76420 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76420 | benjamin.peterson | 2009-11-19 17:19:29 -0600 (Thu, 19 Nov 2009) | 1 line spelling ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Nov 20 00:25:14 2009 @@ -14,7 +14,7 @@ - Add Py3k warnings for parameter names in parenthesis. -- Issue #7362: Give a propery error message for def f((x)=3): pass. +- Issue #7362: Give a proper error message for def f((x)=3): pass. - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. From solipsis at pitrou.net Fri Nov 20 00:48:45 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 20 Nov 2009 00:48:45 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76414): sum=10 Message-ID: <20091119234845.6C3CE17720@ns6635.ovh.net> py3k results for svn r76414 (hg cset 0d83e46d2ad9) -------------------------------------------------- test_urllib leaked [2, 4, 4] references, sum=10 test_zipimport_support leaked [-29, 0, 29] references, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflognemfXa', '-x', 'test_httpservers'] From python-checkins at python.org Fri Nov 20 02:15:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 01:15:54 -0000 Subject: [Python-checkins] r76423 - python/trunk/Python/symtable.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 02:15:53 2009 New Revision: 76423 Log: provide line number for lambdas Modified: python/trunk/Python/symtable.c Modified: python/trunk/Python/symtable.c ============================================================================== --- python/trunk/Python/symtable.c (original) +++ python/trunk/Python/symtable.c Fri Nov 20 02:15:53 2009 @@ -1193,9 +1193,8 @@ return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); - /* XXX how to get line numbers for expressions */ if (!symtable_enter_block(st, lambda, - FunctionBlock, (void *)e, 0)) + FunctionBlock, (void *)e, e->lineno)) return 0; VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); From python-checkins at python.org Fri Nov 20 02:16:59 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 01:16:59 -0000 Subject: [Python-checkins] r76424 - python/trunk/Python/symtable.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 02:16:58 2009 New Revision: 76424 Log: genexps have linenos Modified: python/trunk/Python/symtable.c Modified: python/trunk/Python/symtable.c ============================================================================== --- python/trunk/Python/symtable.c (original) +++ python/trunk/Python/symtable.c Fri Nov 20 02:16:58 2009 @@ -1468,7 +1468,7 @@ VISIT(st, expr, outermost->iter); /* Create generator scope for the rest */ if (!GET_IDENTIFIER(genexpr) || - !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, 0)) { + !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, e->lineno)) { return 0; } st->st_cur->ste_generator = 1; From python-checkins at python.org Fri Nov 20 02:19:42 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 01:19:42 -0000 Subject: [Python-checkins] r76425 - in python/branches/py3k: Python/symtable.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 02:19:41 2009 New Revision: 76425 Log: Merged revisions 76423-76424 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76423 | benjamin.peterson | 2009-11-19 19:15:53 -0600 (Thu, 19 Nov 2009) | 1 line provide line number for lambdas ........ r76424 | benjamin.peterson | 2009-11-19 19:16:58 -0600 (Thu, 19 Nov 2009) | 1 line genexps have linenos ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Python/symtable.c Modified: python/branches/py3k/Python/symtable.c ============================================================================== --- python/branches/py3k/Python/symtable.c (original) +++ python/branches/py3k/Python/symtable.c Fri Nov 20 02:19:41 2009 @@ -1323,9 +1323,8 @@ return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); - /* XXX how to get line numbers for expressions */ if (!symtable_enter_block(st, lambda, - FunctionBlock, (void *)e, 0)) + FunctionBlock, (void *)e, e->lineno)) return 0; VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); @@ -1623,7 +1622,7 @@ VISIT(st, expr, outermost->iter); /* Create comprehension scope for the rest */ if (!scope_name || - !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, 0)) { + !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, e->lineno)) { return 0; } st->st_cur->ste_generator = is_generator; From python-checkins at python.org Fri Nov 20 02:19:48 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 01:19:48 -0000 Subject: [Python-checkins] r76426 - in python/branches/release26-maint: Python/symtable.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 02:19:48 2009 New Revision: 76426 Log: Merged revisions 76423-76424 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76423 | benjamin.peterson | 2009-11-19 19:15:53 -0600 (Thu, 19 Nov 2009) | 1 line provide line number for lambdas ........ r76424 | benjamin.peterson | 2009-11-19 19:16:58 -0600 (Thu, 19 Nov 2009) | 1 line genexps have linenos ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Python/symtable.c Modified: python/branches/release26-maint/Python/symtable.c ============================================================================== --- python/branches/release26-maint/Python/symtable.c (original) +++ python/branches/release26-maint/Python/symtable.c Fri Nov 20 02:19:48 2009 @@ -1217,9 +1217,8 @@ return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); - /* XXX how to get line numbers for expressions */ if (!symtable_enter_block(st, lambda, - FunctionBlock, (void *)e, 0)) + FunctionBlock, (void *)e, e->lineno)) return 0; VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); @@ -1495,7 +1494,7 @@ VISIT(st, expr, outermost->iter); /* Create generator scope for the rest */ if (!GET_IDENTIFIER(genexpr) || - !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, 0)) { + !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, e->lineno)) { return 0; } st->st_cur->ste_generator = 1; From python-checkins at python.org Fri Nov 20 02:21:35 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 01:21:35 -0000 Subject: [Python-checkins] r76427 - in python/branches/release31-maint: Python/symtable.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 02:21:35 2009 New Revision: 76427 Log: Merged revisions 76425 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76425 | benjamin.peterson | 2009-11-19 19:19:41 -0600 (Thu, 19 Nov 2009) | 13 lines Merged revisions 76423-76424 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76423 | benjamin.peterson | 2009-11-19 19:15:53 -0600 (Thu, 19 Nov 2009) | 1 line provide line number for lambdas ........ r76424 | benjamin.peterson | 2009-11-19 19:16:58 -0600 (Thu, 19 Nov 2009) | 1 line genexps have linenos ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Python/symtable.c Modified: python/branches/release31-maint/Python/symtable.c ============================================================================== --- python/branches/release31-maint/Python/symtable.c (original) +++ python/branches/release31-maint/Python/symtable.c Fri Nov 20 02:21:35 2009 @@ -1331,9 +1331,8 @@ return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); - /* XXX how to get line numbers for expressions */ if (!symtable_enter_block(st, lambda, - FunctionBlock, (void *)e, 0)) + FunctionBlock, (void *)e, e->lineno)) return 0; VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); @@ -1631,7 +1630,7 @@ VISIT(st, expr, outermost->iter); /* Create comprehension scope for the rest */ if (!scope_name || - !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, 0)) { + !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, e->lineno)) { return 0; } st->st_cur->ste_generator = is_generator; From python-checkins at python.org Fri Nov 20 03:15:51 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 02:15:51 -0000 Subject: [Python-checkins] r76428 - python/trunk/Python/compile.c Message-ID: Author: benjamin.peterson Date: Fri Nov 20 03:15:50 2009 New Revision: 76428 Log: turn goto into do while loop Modified: python/trunk/Python/compile.c Modified: python/trunk/Python/compile.c ============================================================================== --- python/trunk/Python/compile.c (original) +++ python/trunk/Python/compile.c Fri Nov 20 03:15:50 2009 @@ -3586,49 +3586,47 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) { basicblock *b; - int bsize, totsize, extended_arg_count, last_extended_arg_count = 0; + int bsize, totsize, extended_arg_count = 0, last_extended_arg_count; int i; /* Compute the size of each block and fixup jump args. Replace block pointer with position in bytecode. */ -start: - totsize = 0; - for (i = a->a_nblocks - 1; i >= 0; i--) { - b = a->a_postorder[i]; - bsize = blocksize(b); - b->b_offset = totsize; - totsize += bsize; - } - extended_arg_count = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - bsize = b->b_offset; - for (i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - /* Relative jumps are computed relative to - the instruction pointer after fetching - the jump instruction. - */ - bsize += instrsize(instr); - if (instr->i_jabs) - instr->i_oparg = instr->i_target->b_offset; - else if (instr->i_jrel) { - int delta = instr->i_target->b_offset - bsize; - instr->i_oparg = delta; + do { + totsize = 0; + for (i = a->a_nblocks - 1; i >= 0; i--) { + b = a->a_postorder[i]; + bsize = blocksize(b); + b->b_offset = totsize; + totsize += bsize; + } + last_extended_arg_count = extended_arg_count; + extended_arg_count = 0; + for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + bsize = b->b_offset; + for (i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + /* Relative jumps are computed relative to + the instruction pointer after fetching + the jump instruction. + */ + bsize += instrsize(instr); + if (instr->i_jabs) + instr->i_oparg = instr->i_target->b_offset; + else if (instr->i_jrel) { + int delta = instr->i_target->b_offset - bsize; + instr->i_oparg = delta; + } + else + continue; + if (instr->i_oparg > 0xffff) + extended_arg_count++; } - else - continue; - if (instr->i_oparg > 0xffff) - extended_arg_count++; } - } /* XXX: This is an awful hack that could hurt performance, but on the bright side it should work until we come up with a better solution. - In the meantime, should the goto be dropped in favor - of a loop? - The issue is that in the first loop blocksize() is called which calls instrsize() which requires i_oparg be set appropriately. There is a bootstrap problem because @@ -3639,10 +3637,7 @@ ones in jump instructions. So this should converge fairly quickly. */ - if (last_extended_arg_count != extended_arg_count) { - last_extended_arg_count = extended_arg_count; - goto start; - } + } while (last_extended_arg_count != extended_arg_count); } static PyObject * From python-checkins at python.org Fri Nov 20 03:56:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 02:56:43 -0000 Subject: [Python-checkins] r76429 - python/trunk/Lib/os.py Message-ID: Author: benjamin.peterson Date: Fri Nov 20 03:56:43 2009 New Revision: 76429 Log: avoid function import Modified: python/trunk/Lib/os.py Modified: python/trunk/Lib/os.py ============================================================================== --- python/trunk/Lib/os.py (original) +++ python/trunk/Lib/os.py Fri Nov 20 03:56:43 2009 @@ -263,7 +263,7 @@ dirs.remove('CVS') # don't visit CVS directories """ - from os.path import join, isdir, islink + islink, join, isdir = path.islink, path.join, path.isdir # We may not have read permission for top, in which case we can't # get a list of the files the directory contains. os.path.walk @@ -289,9 +289,9 @@ if topdown: yield top, dirs, nondirs for name in dirs: - path = join(top, name) - if followlinks or not islink(path): - for x in walk(path, topdown, onerror, followlinks): + new_path = join(top, name) + if followlinks or not islink(new_path): + for x in walk(new_path, topdown, onerror, followlinks): yield x if not topdown: yield top, dirs, nondirs From python-checkins at python.org Fri Nov 20 04:15:08 2009 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 20 Nov 2009 03:15:08 -0000 Subject: [Python-checkins] r76429 - svn:log Message-ID: Author: benjamin.peterson Revision: 76429 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -avoid function import \ No newline at end of file +avoid doing an uneeded import in a function From nnorwitz at gmail.com Fri Nov 20 11:54:32 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 20 Nov 2009 05:54:32 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091120105432.GA31180@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 339, 0] references, sum=339 Less important issues: ---------------------- test_zipimport_support leaked [0, -25, 25] references, sum=0 From python-checkins at python.org Fri Nov 20 14:29:44 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 20 Nov 2009 13:29:44 -0000 Subject: [Python-checkins] r76430 - python/trunk/Doc/library/socketserver.rst Message-ID: Author: r.david.murray Date: Fri Nov 20 14:29:43 2009 New Revision: 76430 Log: Issue 7363: fix indentation in socketserver udpserver example. Modified: python/trunk/Doc/library/socketserver.rst Modified: python/trunk/Doc/library/socketserver.rst ============================================================================== --- python/trunk/Doc/library/socketserver.rst (original) +++ python/trunk/Doc/library/socketserver.rst Fri Nov 20 14:29:43 2009 @@ -455,9 +455,9 @@ socket.sendto(data.upper(), self.client_address) if __name__ == "__main__": - HOST, PORT = "localhost", 9999 - server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler) - server.serve_forever() + HOST, PORT = "localhost", 9999 + server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler) + server.serve_forever() This is the client side:: From dickinsm at gmail.com Fri Nov 20 18:22:29 2009 From: dickinsm at gmail.com (Mark Dickinson) Date: Fri, 20 Nov 2009 17:22:29 +0000 Subject: [Python-checkins] r76403 - in python/trunk: Misc/NEWS configure configure.in In-Reply-To: <4b05721d.1767f10a.363d.fffff2a7SMTPIN_ADDED@mx.google.com> References: <4b05721d.1767f10a.363d.fffff2a7SMTPIN_ADDED@mx.google.com> Message-ID: <5c6f2a5d0911200922j1732e39bk5447c5b988747ba3@mail.gmail.com> On Thu, Nov 19, 2009 at 4:28 PM, ronald.oussoren wrote: > Author: ronald.oussoren > Date: Thu Nov 19 17:25:21 2009 > New Revision: 76403 > > Log: > Fix for issue #7085 [...] > Modified: python/trunk/configure > ============================================================================== > --- python/trunk/configure ? ? ?(original) > +++ python/trunk/configure ? ? ?Thu Nov 19 17:25:21 2009 > @@ -1,5 +1,5 @@ > ?#! /bin/sh > -# From configure.in Revision: 76300 . > +# From configure.in Revision: 76308 . > ?# Guess values for system-dependent variables and create Makefiles. > ?# Generated by GNU Autoconf 2.61 for python 2.7. > ?# > @@ -3865,7 +3865,7 @@ > ? { echo "$as_me:$LINENO: result: no" >&5 > ?echo "${ECHO_T}no" >&6; } > ?fi > -rm -f conftest* > +rm -f -r conftest* > > > > @@ -5413,7 +5413,7 @@ > ?else > ? ac_cv_header_stdc=no > ?fi > -rm -f conftest* > +rm -f -r conftest* > > ?fi > > @@ -5434,7 +5434,7 @@ > ?else > ? ac_cv_header_stdc=no > ?fi > -rm -f conftest* > +rm -f -r conftest* [Snip lots more occurrences of -rm -f conftext* \n +rm -f -r conftest* ] It looks as though the autoconf provided with OS X 10.6 isn't quite standard... Mark From python-checkins at python.org Fri Nov 20 20:27:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 20 Nov 2009 19:27:44 -0000 Subject: [Python-checkins] r76431 - python/trunk/configure Message-ID: Author: mark.dickinson Date: Fri Nov 20 20:27:43 2009 New Revision: 76431 Log: Regenerate configure with GNU autoconf 2.61. Modified: python/trunk/configure Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Fri Nov 20 20:27:43 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76308 . +# From configure.in Revision: 76403 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -3865,7 +3865,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f -r conftest* +rm -f conftest* @@ -5413,7 +5413,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -5434,7 +5434,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6532,7 +6532,7 @@ fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -7062,7 +7062,7 @@ else ac_cv_type_uid_t=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15722,7 +15722,7 @@ else unistd_defines_pthreads=no fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -17336,7 +17336,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f -r conftest* +rm -f conftest* ;; kame) @@ -17359,7 +17359,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-glibc) @@ -17380,7 +17380,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-inet6) @@ -17418,7 +17418,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; v6d) @@ -17441,7 +17441,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f -r conftest* +rm -f conftest* ;; zeta) @@ -17463,7 +17463,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; esac @@ -25744,7 +25744,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -25763,7 +25763,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi @@ -26033,7 +26033,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi From python-checkins at python.org Fri Nov 20 20:30:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 20 Nov 2009 19:30:23 -0000 Subject: [Python-checkins] r76432 - in python/trunk: Lib/test/test_multiprocessing.py Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h configure configure.in setup.py Message-ID: Author: mark.dickinson Date: Fri Nov 20 20:30:22 2009 New Revision: 76432 Log: Issue #7272: Add configure test to detect whether sem_open works properly, and use this to skip test_multiprocessing on platforms where sem_open raises a signal. This should fix some FreeBSD buildbot failures for test_multiprocessing. Modified: python/trunk/Lib/test/test_multiprocessing.py python/trunk/Modules/_multiprocessing/multiprocessing.c python/trunk/Modules/_multiprocessing/multiprocessing.h python/trunk/configure python/trunk/configure.in python/trunk/setup.py Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Fri Nov 20 20:30:22 2009 @@ -17,7 +17,7 @@ import socket import random import logging -import test_support +from test import test_support from StringIO import StringIO Modified: python/trunk/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.c (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.c Fri Nov 20 20:30:22 2009 @@ -250,7 +250,8 @@ Py_INCREF(&ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); -#if defined(MS_WINDOWS) || defined(HAVE_SEM_OPEN) +#if defined(MS_WINDOWS) || \ + (defined(HAVE_SEM_OPEN) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return; @@ -297,7 +298,7 @@ Py_DECREF(temp); Py_DECREF(value); return; } \ Py_DECREF(value) -#ifdef HAVE_SEM_OPEN +#if defined(HAVE_SEM_OPEN) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) ADD_FLAG(HAVE_SEM_OPEN); #endif #ifdef HAVE_SEM_TIMEDWAIT Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.h (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.h Fri Nov 20 20:30:22 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# ifdef HAVE_SEM_OPEN +# if defined(HAVE_SEM_OPEN) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) # include typedef sem_t *SEM_HANDLE; # endif Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Fri Nov 20 20:30:22 2009 @@ -23782,6 +23782,91 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +{ echo "$as_me:$LINENO: checking whether POSIX semaphores are enabled" >&5 +echo $ECHO_N "checking whether POSIX semaphores are enabled... $ECHO_C" >&6; } +if test "${ac_cv_posix_semaphores_enabled+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_posix_semaphores_enabled=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_posix_semaphores_enabled=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_posix_semaphores_enabled=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_posix_semaphores_enabled" >&5 +echo "${ECHO_T}$ac_cv_posix_semaphores_enabled" >&6; } +if test $ac_cv_posix_semaphores_enabled = no +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_POSIX_SEMAPHORES 1 +_ACEOF + +fi + + # Multiprocessing check for broken sem_getvalue { echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Fri Nov 20 20:30:22 2009 @@ -3387,6 +3387,41 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +AC_MSG_CHECKING(whether POSIX semaphores are enabled) +AC_CACHE_VAL(ac_cv_posix_semaphores_enabled, +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} +], ac_cv_posix_semaphores_enabled=yes, + ac_cv_posix_semaphores_enabled=no, + ac_cv_posix_semaphores_enabled=yes) +) +AC_MSG_RESULT($ac_cv_posix_semaphores_enabled) +if test $ac_cv_posix_semaphores_enabled = no +then + AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + [Define if the Posix semaphores do not work on your system]) +fi + + # Multiprocessing check for broken sem_getvalue AC_MSG_CHECKING(for broken sem_getvalue) AC_CACHE_VAL(ac_cv_broken_sem_getvalue, Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Fri Nov 20 20:30:22 2009 @@ -1315,7 +1315,8 @@ multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c', '_multiprocessing/socket_connection.c' ] - if sysconfig.get_config_var('HAVE_SEM_OPEN'): + if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not + sysconfig.get_config_var('HAVE_BROKEN_POSIX_SEMAPHORES')): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From nnorwitz at gmail.com Fri Nov 20 22:24:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 20 Nov 2009 16:24:43 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091120212443.GA24206@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:651: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1984: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [876666 refs] From nnorwitz at gmail.com Fri Nov 20 23:52:41 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 20 Nov 2009 17:52:41 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091120225241.GA23780@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 91, -11] references, sum=80 Less important issues: ---------------------- test_ssl leaked [-420, 81, 339] references, sum=0 From solipsis at pitrou.net Sat Nov 21 00:47:10 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 21 Nov 2009 00:47:10 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76425): sum=14 Message-ID: <20091120234710.89DFB17720@ns6635.ovh.net> py3k results for svn r76425 (hg cset 8451a1a0ceb6) -------------------------------------------------- test_urllib leaked [6, 4, 4] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogJREG_v', '-x', 'test_httpservers'] From nnorwitz at gmail.com Sat Nov 21 10:24:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 21 Nov 2009 04:24:55 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091121092455.GA28997@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:651: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1984: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [876669 refs] From python-checkins at python.org Sat Nov 21 15:01:56 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 14:01:56 -0000 Subject: [Python-checkins] r76433 - in python/trunk: Doc/includes/mp_distributing.py Doc/library/multiprocessing.rst Lib/multiprocessing/queues.py Message-ID: Author: jesse.noller Date: Sat Nov 21 15:01:56 2009 New Revision: 76433 Log: issue5738: The distribution example was confusing, and out of date. It's too large to include inline in the docs as well. It belongs in an addons module outside the stdlib. Removing. Removed: python/trunk/Doc/includes/mp_distributing.py Modified: python/trunk/Doc/library/multiprocessing.rst python/trunk/Lib/multiprocessing/queues.py Deleted: python/trunk/Doc/includes/mp_distributing.py ============================================================================== --- python/trunk/Doc/includes/mp_distributing.py Sat Nov 21 15:01:56 2009 +++ (empty file) @@ -1,364 +0,0 @@ -# -# Module to allow spawning of processes on foreign host -# -# Depends on `multiprocessing` package -- tested with `processing-0.60` -# -# Copyright (c) 2006-2008, R Oudkerk -# All rights reserved. -# - -__all__ = ['Cluster', 'Host', 'get_logger', 'current_process'] - -# -# Imports -# - -import sys -import os -import tarfile -import shutil -import subprocess -import logging -import itertools -import Queue - -try: - import cPickle as pickle -except ImportError: - import pickle - -from multiprocessing import Process, current_process, cpu_count -from multiprocessing import util, managers, connection, forking, pool - -# -# Logging -# - -def get_logger(): - return _logger - -_logger = logging.getLogger('distributing') -_logger.propagate = 0 - -_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) -_handler = logging.StreamHandler() -_handler.setFormatter(_formatter) -_logger.addHandler(_handler) - -info = _logger.info -debug = _logger.debug - -# -# Get number of cpus -# - -try: - slot_count = cpu_count() -except NotImplemented: - slot_count = 1 - -# -# Manager type which spawns subprocesses -# - -class HostManager(managers.SyncManager): - ''' - Manager type used for spawning processes on a (presumably) foreign host - ''' - def __init__(self, address, authkey): - managers.SyncManager.__init__(self, address, authkey) - self._name = 'Host-unknown' - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - if hasattr(sys.modules['__main__'], '__file__'): - main_path = os.path.basename(sys.modules['__main__'].__file__) - else: - main_path = None - data = pickle.dumps((target, args, kwargs)) - p = self._RemoteProcess(data, main_path) - if name is None: - temp = self._name.split('Host-')[-1] + '/Process-%s' - name = temp % ':'.join(map(str, p.get_identity())) - p.set_name(name) - return p - - @classmethod - def from_address(cls, address, authkey): - manager = cls(address, authkey) - managers.transact(address, authkey, 'dummy') - manager._state.value = managers.State.STARTED - manager._name = 'Host-%s:%s' % manager.address - manager.shutdown = util.Finalize( - manager, HostManager._finalize_host, - args=(manager._address, manager._authkey, manager._name), - exitpriority=-10 - ) - return manager - - @staticmethod - def _finalize_host(address, authkey, name): - managers.transact(address, authkey, 'shutdown') - - def __repr__(self): - return '' % self._name - -# -# Process subclass representing a process on (possibly) a remote machine -# - -class RemoteProcess(Process): - ''' - Represents a process started on a remote host - ''' - def __init__(self, data, main_path): - assert not main_path or os.path.basename(main_path) == main_path - Process.__init__(self) - self._data = data - self._main_path = main_path - - def _bootstrap(self): - forking.prepare({'main_path': self._main_path}) - self._target, self._args, self._kwargs = pickle.loads(self._data) - return Process._bootstrap(self) - - def get_identity(self): - return self._identity - -HostManager.register('_RemoteProcess', RemoteProcess) - -# -# A Pool class that uses a cluster -# - -class DistributedPool(pool.Pool): - - def __init__(self, cluster, processes=None, initializer=None, initargs=()): - self._cluster = cluster - self.Process = cluster.Process - pool.Pool.__init__(self, processes or len(cluster), - initializer, initargs) - - def _setup_queues(self): - self._inqueue = self._cluster._SettableQueue() - self._outqueue = self._cluster._SettableQueue() - self._quick_put = self._inqueue.put - self._quick_get = self._outqueue.get - - @staticmethod - def _help_stuff_finish(inqueue, task_handler, size): - inqueue.set_contents([None] * size) - -# -# Manager type which starts host managers on other machines -# - -def LocalProcess(**kwds): - p = Process(**kwds) - p.set_name('localhost/' + p.name) - return p - -class Cluster(managers.SyncManager): - ''' - Represents collection of slots running on various hosts. - - `Cluster` is a subclass of `SyncManager` so it allows creation of - various types of shared objects. - ''' - def __init__(self, hostlist, modules): - managers.SyncManager.__init__(self, address=('localhost', 0)) - self._hostlist = hostlist - self._modules = modules - if __name__ not in modules: - modules.append(__name__) - files = [sys.modules[name].__file__ for name in modules] - for i, file in enumerate(files): - if file.endswith('.pyc') or file.endswith('.pyo'): - files[i] = file[:-4] + '.py' - self._files = [os.path.abspath(file) for file in files] - - def start(self): - managers.SyncManager.start(self) - - l = connection.Listener(family='AF_INET', authkey=self._authkey) - - for i, host in enumerate(self._hostlist): - host._start_manager(i, self._authkey, l.address, self._files) - - for host in self._hostlist: - if host.hostname != 'localhost': - conn = l.accept() - i, address, cpus = conn.recv() - conn.close() - other_host = self._hostlist[i] - other_host.manager = HostManager.from_address(address, - self._authkey) - other_host.slots = other_host.slots or cpus - other_host.Process = other_host.manager.Process - else: - host.slots = host.slots or slot_count - host.Process = LocalProcess - - self._slotlist = [ - Slot(host) for host in self._hostlist for i in range(host.slots) - ] - self._slot_iterator = itertools.cycle(self._slotlist) - self._base_shutdown = self.shutdown - del self.shutdown - - def shutdown(self): - for host in self._hostlist: - if host.hostname != 'localhost': - host.manager.shutdown() - self._base_shutdown() - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - slot = self._slot_iterator.next() - return slot.Process( - group=group, target=target, name=name, args=args, kwargs=kwargs - ) - - def Pool(self, processes=None, initializer=None, initargs=()): - return DistributedPool(self, processes, initializer, initargs) - - def __getitem__(self, i): - return self._slotlist[i] - - def __len__(self): - return len(self._slotlist) - - def __iter__(self): - return iter(self._slotlist) - -# -# Queue subclass used by distributed pool -# - -class SettableQueue(Queue.Queue): - def empty(self): - return not self.queue - def full(self): - return self.maxsize > 0 and len(self.queue) == self.maxsize - def set_contents(self, contents): - # length of contents must be at least as large as the number of - # threads which have potentially called get() - self.not_empty.acquire() - try: - self.queue.clear() - self.queue.extend(contents) - self.not_empty.notifyAll() - finally: - self.not_empty.release() - -Cluster.register('_SettableQueue', SettableQueue) - -# -# Class representing a notional cpu in the cluster -# - -class Slot(object): - def __init__(self, host): - self.host = host - self.Process = host.Process - -# -# Host -# - -class Host(object): - ''' - Represents a host to use as a node in a cluster. - - `hostname` gives the name of the host. If hostname is not - "localhost" then ssh is used to log in to the host. To log in as - a different user use a host name of the form - "username at somewhere.org" - - `slots` is used to specify the number of slots for processes on - the host. This affects how often processes will be allocated to - this host. Normally this should be equal to the number of cpus on - that host. - ''' - def __init__(self, hostname, slots=None): - self.hostname = hostname - self.slots = slots - - def _start_manager(self, index, authkey, address, files): - if self.hostname != 'localhost': - tempdir = copy_to_remote_temporary_directory(self.hostname, files) - debug('startup files copied to %s:%s', self.hostname, tempdir) - p = subprocess.Popen( - ['ssh', self.hostname, 'python', '-c', - '"import os; os.chdir(%r); ' - 'from distributing import main; main()"' % tempdir], - stdin=subprocess.PIPE - ) - data = dict( - name='BoostrappingHost', index=index, - dist_log_level=_logger.getEffectiveLevel(), - dir=tempdir, authkey=str(authkey), parent_address=address - ) - pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL) - p.stdin.close() - -# -# Copy files to remote directory, returning name of directory -# - -unzip_code = '''" -import tempfile, os, sys, tarfile -tempdir = tempfile.mkdtemp(prefix='distrib-') -os.chdir(tempdir) -tf = tarfile.open(fileobj=sys.stdin, mode='r|gz') -for ti in tf: - tf.extract(ti) -print tempdir -"''' - -def copy_to_remote_temporary_directory(host, files): - p = subprocess.Popen( - ['ssh', host, 'python', '-c', unzip_code], - stdout=subprocess.PIPE, stdin=subprocess.PIPE - ) - tf = tarfile.open(fileobj=p.stdin, mode='w|gz') - for name in files: - tf.add(name, os.path.basename(name)) - tf.close() - p.stdin.close() - return p.stdout.read().rstrip() - -# -# Code which runs a host manager -# - -def main(): - # get data from parent over stdin - data = pickle.load(sys.stdin) - sys.stdin.close() - - # set some stuff - _logger.setLevel(data['dist_log_level']) - forking.prepare(data) - - # create server for a `HostManager` object - server = managers.Server(HostManager._registry, ('', 0), data['authkey']) - current_process()._server = server - - # report server address and number of cpus back to parent - conn = connection.Client(data['parent_address'], authkey=data['authkey']) - conn.send((data['index'], server.address, slot_count)) - conn.close() - - # set name etc - current_process().set_name('Host-%s:%s' % server.address) - util._run_after_forkers() - - # register a cleanup function - def cleanup(directory): - debug('removing directory %s', directory) - shutil.rmtree(directory) - debug('shutting down host manager') - util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0) - - # start host manager - debug('remote host manager starting in %s', data['dir']) - server.serve_forever() Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Sat Nov 21 15:01:56 2009 @@ -2230,10 +2230,3 @@ .. literalinclude:: ../includes/mp_benchmarks.py -An example/demo of how to use the :class:`managers.SyncManager`, :class:`Process` -and others to build a system which can distribute processes and work via a -distributed queue to a "cluster" of machines on a network, accessible via SSH. -You will need to have private key authentication for all hosts configured for -this to work. - -.. literalinclude:: ../includes/mp_distributing.py Modified: python/trunk/Lib/multiprocessing/queues.py ============================================================================== --- python/trunk/Lib/multiprocessing/queues.py (original) +++ python/trunk/Lib/multiprocessing/queues.py Sat Nov 21 15:01:56 2009 @@ -47,6 +47,8 @@ if sys.platform != 'win32': register_after_fork(self, Queue._after_fork) + self.getv = 0 + def __getstate__(self): assert_spawning(self) return (self._maxsize, self._reader, self._writer, @@ -71,6 +73,8 @@ self._poll = self._reader.poll def put(self, obj, block=True, timeout=None): + if not isinstance(obj, list): + debug('put: %s', obj) assert not self._closed if not self._sem.acquire(block, timeout): raise Full @@ -85,11 +89,15 @@ self._notempty.release() def get(self, block=True, timeout=None): + self.getv += 1 + debug('self.getv: %s', self.getv) if block and timeout is None: self._rlock.acquire() try: res = self._recv() self._sem.release() + if not isinstance(res, list): + debug('get: %s', res) return res finally: self._rlock.release() @@ -104,6 +112,8 @@ raise Empty res = self._recv() self._sem.release() + if not isinstance(res, list): + debug('get: %s', res) return res finally: self._rlock.release() @@ -229,16 +239,22 @@ try: while 1: obj = bpopleft() + if not isinstance(obj, list): + debug('feeder thread got: %s', obj) if obj is sentinel: debug('feeder thread got sentinel -- exiting') close() return - if wacquire is None: + if not isinstance(obj, list): + debug('sending to pipe: %s', obj) send(obj) else: - wacquire() + debug('waiting on wacquire') + wacquire(timeout=30) try: + if not isinstance(obj, list): + debug('sending to pipe: %s', obj) send(obj) finally: wrelease() From python-checkins at python.org Sat Nov 21 15:06:25 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 14:06:25 -0000 Subject: [Python-checkins] r76434 - python/trunk/Lib/multiprocessing/queues.py Message-ID: Author: jesse.noller Date: Sat Nov 21 15:06:24 2009 New Revision: 76434 Log: revert unintended change to multiprocessing/queues.py Modified: python/trunk/Lib/multiprocessing/queues.py Modified: python/trunk/Lib/multiprocessing/queues.py ============================================================================== --- python/trunk/Lib/multiprocessing/queues.py (original) +++ python/trunk/Lib/multiprocessing/queues.py Sat Nov 21 15:06:24 2009 @@ -47,8 +47,6 @@ if sys.platform != 'win32': register_after_fork(self, Queue._after_fork) - self.getv = 0 - def __getstate__(self): assert_spawning(self) return (self._maxsize, self._reader, self._writer, @@ -73,8 +71,6 @@ self._poll = self._reader.poll def put(self, obj, block=True, timeout=None): - if not isinstance(obj, list): - debug('put: %s', obj) assert not self._closed if not self._sem.acquire(block, timeout): raise Full @@ -89,15 +85,11 @@ self._notempty.release() def get(self, block=True, timeout=None): - self.getv += 1 - debug('self.getv: %s', self.getv) if block and timeout is None: self._rlock.acquire() try: res = self._recv() self._sem.release() - if not isinstance(res, list): - debug('get: %s', res) return res finally: self._rlock.release() @@ -112,8 +104,6 @@ raise Empty res = self._recv() self._sem.release() - if not isinstance(res, list): - debug('get: %s', res) return res finally: self._rlock.release() @@ -239,22 +229,16 @@ try: while 1: obj = bpopleft() - if not isinstance(obj, list): - debug('feeder thread got: %s', obj) if obj is sentinel: debug('feeder thread got sentinel -- exiting') close() return + if wacquire is None: - if not isinstance(obj, list): - debug('sending to pipe: %s', obj) send(obj) else: - debug('waiting on wacquire') - wacquire(timeout=30) + wacquire() try: - if not isinstance(obj, list): - debug('sending to pipe: %s', obj) send(obj) finally: wrelease() From python-checkins at python.org Sat Nov 21 15:20:14 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 14:20:14 -0000 Subject: [Python-checkins] r76435 - in python/branches/py3k: Doc/includes/mp_distributing.py Doc/library/multiprocessing.rst Message-ID: Author: jesse.noller Date: Sat Nov 21 15:20:14 2009 New Revision: 76435 Log: Merged revisions 76433 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76433 | jesse.noller | 2009-11-21 09:01:56 -0500 (Sat, 21 Nov 2009) | 1 line issue5738: The distribution example was confusing, and out of date. It's too large to include inline in the docs as well. It belongs in an addons module outside the stdlib. Removing. ........ Removed: python/branches/py3k/Doc/includes/mp_distributing.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/multiprocessing.rst Deleted: python/branches/py3k/Doc/includes/mp_distributing.py ============================================================================== --- python/branches/py3k/Doc/includes/mp_distributing.py Sat Nov 21 15:20:14 2009 +++ (empty file) @@ -1,364 +0,0 @@ -# -# Module to allow spawning of processes on foreign host -# -# Depends on `multiprocessing` package -- tested with `processing-0.60` -# -# Copyright (c) 2006-2008, R Oudkerk -# All rights reserved. -# - -__all__ = ['Cluster', 'Host', 'get_logger', 'current_process'] - -# -# Imports -# - -import sys -import os -import tarfile -import shutil -import subprocess -import logging -import itertools -import queue - -try: - import pickle as pickle -except ImportError: - import pickle - -from multiprocessing import Process, current_process, cpu_count -from multiprocessing import util, managers, connection, forking, pool - -# -# Logging -# - -def get_logger(): - return _logger - -_logger = logging.getLogger('distributing') -_logger.propagate = 0 - -_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) -_handler = logging.StreamHandler() -_handler.setFormatter(_formatter) -_logger.addHandler(_handler) - -info = _logger.info -debug = _logger.debug - -# -# Get number of cpus -# - -try: - slot_count = cpu_count() -except NotImplemented: - slot_count = 1 - -# -# Manager type which spawns subprocesses -# - -class HostManager(managers.SyncManager): - ''' - Manager type used for spawning processes on a (presumably) foreign host - ''' - def __init__(self, address, authkey): - managers.SyncManager.__init__(self, address, authkey) - self._name = 'Host-unknown' - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - if hasattr(sys.modules['__main__'], '__file__'): - main_path = os.path.basename(sys.modules['__main__'].__file__) - else: - main_path = None - data = pickle.dumps((target, args, kwargs)) - p = self._RemoteProcess(data, main_path) - if name is None: - temp = self._name.split('Host-')[-1] + '/Process-%s' - name = temp % ':'.join(map(str, p.get_identity())) - p.set_name(name) - return p - - @classmethod - def from_address(cls, address, authkey): - manager = cls(address, authkey) - managers.transact(address, authkey, 'dummy') - manager._state.value = managers.State.STARTED - manager._name = 'Host-%s:%s' % manager.address - manager.shutdown = util.Finalize( - manager, HostManager._finalize_host, - args=(manager._address, manager._authkey, manager._name), - exitpriority=-10 - ) - return manager - - @staticmethod - def _finalize_host(address, authkey, name): - managers.transact(address, authkey, 'shutdown') - - def __repr__(self): - return '' % self._name - -# -# Process subclass representing a process on (possibly) a remote machine -# - -class RemoteProcess(Process): - ''' - Represents a process started on a remote host - ''' - def __init__(self, data, main_path): - assert not main_path or os.path.basename(main_path) == main_path - Process.__init__(self) - self._data = data - self._main_path = main_path - - def _bootstrap(self): - forking.prepare({'main_path': self._main_path}) - self._target, self._args, self._kwargs = pickle.loads(self._data) - return Process._bootstrap(self) - - def get_identity(self): - return self._identity - -HostManager.register('_RemoteProcess', RemoteProcess) - -# -# A Pool class that uses a cluster -# - -class DistributedPool(pool.Pool): - - def __init__(self, cluster, processes=None, initializer=None, initargs=()): - self._cluster = cluster - self.Process = cluster.Process - pool.Pool.__init__(self, processes or len(cluster), - initializer, initargs) - - def _setup_queues(self): - self._inqueue = self._cluster._SettableQueue() - self._outqueue = self._cluster._SettableQueue() - self._quick_put = self._inqueue.put - self._quick_get = self._outqueue.get - - @staticmethod - def _help_stuff_finish(inqueue, task_handler, size): - inqueue.set_contents([None] * size) - -# -# Manager type which starts host managers on other machines -# - -def LocalProcess(**kwds): - p = Process(**kwds) - p.set_name('localhost/' + p.name) - return p - -class Cluster(managers.SyncManager): - ''' - Represents collection of slots running on various hosts. - - `Cluster` is a subclass of `SyncManager` so it allows creation of - various types of shared objects. - ''' - def __init__(self, hostlist, modules): - managers.SyncManager.__init__(self, address=('localhost', 0)) - self._hostlist = hostlist - self._modules = modules - if __name__ not in modules: - modules.append(__name__) - files = [sys.modules[name].__file__ for name in modules] - for i, file in enumerate(files): - if file.endswith('.pyc') or file.endswith('.pyo'): - files[i] = file[:-4] + '.py' - self._files = [os.path.abspath(file) for file in files] - - def start(self): - managers.SyncManager.start(self) - - l = connection.Listener(family='AF_INET', authkey=self._authkey) - - for i, host in enumerate(self._hostlist): - host._start_manager(i, self._authkey, l.address, self._files) - - for host in self._hostlist: - if host.hostname != 'localhost': - conn = l.accept() - i, address, cpus = conn.recv() - conn.close() - other_host = self._hostlist[i] - other_host.manager = HostManager.from_address(address, - self._authkey) - other_host.slots = other_host.slots or cpus - other_host.Process = other_host.manager.Process - else: - host.slots = host.slots or slot_count - host.Process = LocalProcess - - self._slotlist = [ - Slot(host) for host in self._hostlist for i in range(host.slots) - ] - self._slot_iterator = itertools.cycle(self._slotlist) - self._base_shutdown = self.shutdown - del self.shutdown - - def shutdown(self): - for host in self._hostlist: - if host.hostname != 'localhost': - host.manager.shutdown() - self._base_shutdown() - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - slot = next(self._slot_iterator) - return slot.Process( - group=group, target=target, name=name, args=args, kwargs=kwargs - ) - - def Pool(self, processes=None, initializer=None, initargs=()): - return DistributedPool(self, processes, initializer, initargs) - - def __getitem__(self, i): - return self._slotlist[i] - - def __len__(self): - return len(self._slotlist) - - def __iter__(self): - return iter(self._slotlist) - -# -# Queue subclass used by distributed pool -# - -class SettableQueue(queue.Queue): - def empty(self): - return not self.queue - def full(self): - return self.maxsize > 0 and len(self.queue) == self.maxsize - def set_contents(self, contents): - # length of contents must be at least as large as the number of - # threads which have potentially called get() - self.not_empty.acquire() - try: - self.queue.clear() - self.queue.extend(contents) - self.not_empty.notifyAll() - finally: - self.not_empty.release() - -Cluster.register('_SettableQueue', SettableQueue) - -# -# Class representing a notional cpu in the cluster -# - -class Slot(object): - def __init__(self, host): - self.host = host - self.Process = host.Process - -# -# Host -# - -class Host(object): - ''' - Represents a host to use as a node in a cluster. - - `hostname` gives the name of the host. If hostname is not - "localhost" then ssh is used to log in to the host. To log in as - a different user use a host name of the form - "username at somewhere.org" - - `slots` is used to specify the number of slots for processes on - the host. This affects how often processes will be allocated to - this host. Normally this should be equal to the number of cpus on - that host. - ''' - def __init__(self, hostname, slots=None): - self.hostname = hostname - self.slots = slots - - def _start_manager(self, index, authkey, address, files): - if self.hostname != 'localhost': - tempdir = copy_to_remote_temporary_directory(self.hostname, files) - debug('startup files copied to %s:%s', self.hostname, tempdir) - p = subprocess.Popen( - ['ssh', self.hostname, 'python', '-c', - '"import os; os.chdir(%r); ' - 'from distributing import main; main()"' % tempdir], - stdin=subprocess.PIPE - ) - data = dict( - name='BoostrappingHost', index=index, - dist_log_level=_logger.getEffectiveLevel(), - dir=tempdir, authkey=str(authkey), parent_address=address - ) - pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL) - p.stdin.close() - -# -# Copy files to remote directory, returning name of directory -# - -unzip_code = '''" -import tempfile, os, sys, tarfile -tempdir = tempfile.mkdtemp(prefix='distrib-') -os.chdir(tempdir) -tf = tarfile.open(fileobj=sys.stdin, mode='r|gz') -for ti in tf: - tf.extract(ti) -print tempdir -"''' - -def copy_to_remote_temporary_directory(host, files): - p = subprocess.Popen( - ['ssh', host, 'python', '-c', unzip_code], - stdout=subprocess.PIPE, stdin=subprocess.PIPE - ) - tf = tarfile.open(fileobj=p.stdin, mode='w|gz') - for name in files: - tf.add(name, os.path.basename(name)) - tf.close() - p.stdin.close() - return p.stdout.read().rstrip() - -# -# Code which runs a host manager -# - -def main(): - # get data from parent over stdin - data = pickle.load(sys.stdin) - sys.stdin.close() - - # set some stuff - _logger.setLevel(data['dist_log_level']) - forking.prepare(data) - - # create server for a `HostManager` object - server = managers.Server(HostManager._registry, ('', 0), data['authkey']) - current_process()._server = server - - # report server address and number of cpus back to parent - conn = connection.Client(data['parent_address'], authkey=data['authkey']) - conn.send((data['index'], server.address, slot_count)) - conn.close() - - # set name etc - current_process().set_name('Host-%s:%s' % server.address) - util._run_after_forkers() - - # register a cleanup function - def cleanup(directory): - debug('removing directory %s', directory) - shutil.rmtree(directory) - debug('shutting down host manager') - util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0) - - # start host manager - debug('remote host manager starting in %s', data['dir']) - server.serve_forever() Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Sat Nov 21 15:20:14 2009 @@ -2228,10 +2228,3 @@ .. literalinclude:: ../includes/mp_benchmarks.py -An example/demo of how to use the :class:`managers.SyncManager`, :class:`Process` -and others to build a system which can distribute processes and work via a -distributed queue to a "cluster" of machines on a network, accessible via SSH. -You will need to have private key authentication for all hosts configured for -this to work. - -.. literalinclude:: ../includes/mp_distributing.py From python-checkins at python.org Sat Nov 21 15:23:47 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 14:23:47 -0000 Subject: [Python-checkins] r76436 - in python/branches/release26-maint: Doc/includes/mp_distributing.py Doc/library/multiprocessing.rst Message-ID: Author: jesse.noller Date: Sat Nov 21 15:23:46 2009 New Revision: 76436 Log: Merged revisions 76433 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76433 | jesse.noller | 2009-11-21 09:01:56 -0500 (Sat, 21 Nov 2009) | 1 line issue5738: The distribution example was confusing, and out of date. It's too large to include inline in the docs as well. It belongs in an addons module outside the stdlib. Removing. ........ Removed: python/branches/release26-maint/Doc/includes/mp_distributing.py Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/multiprocessing.rst Deleted: python/branches/release26-maint/Doc/includes/mp_distributing.py ============================================================================== --- python/branches/release26-maint/Doc/includes/mp_distributing.py Sat Nov 21 15:23:46 2009 +++ (empty file) @@ -1,364 +0,0 @@ -# -# Module to allow spawning of processes on foreign host -# -# Depends on `multiprocessing` package -- tested with `processing-0.60` -# -# Copyright (c) 2006-2008, R Oudkerk -# All rights reserved. -# - -__all__ = ['Cluster', 'Host', 'get_logger', 'current_process'] - -# -# Imports -# - -import sys -import os -import tarfile -import shutil -import subprocess -import logging -import itertools -import Queue - -try: - import cPickle as pickle -except ImportError: - import pickle - -from multiprocessing import Process, current_process, cpu_count -from multiprocessing import util, managers, connection, forking, pool - -# -# Logging -# - -def get_logger(): - return _logger - -_logger = logging.getLogger('distributing') -_logger.propagate = 0 - -_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) -_handler = logging.StreamHandler() -_handler.setFormatter(_formatter) -_logger.addHandler(_handler) - -info = _logger.info -debug = _logger.debug - -# -# Get number of cpus -# - -try: - slot_count = cpu_count() -except NotImplemented: - slot_count = 1 - -# -# Manager type which spawns subprocesses -# - -class HostManager(managers.SyncManager): - ''' - Manager type used for spawning processes on a (presumably) foreign host - ''' - def __init__(self, address, authkey): - managers.SyncManager.__init__(self, address, authkey) - self._name = 'Host-unknown' - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - if hasattr(sys.modules['__main__'], '__file__'): - main_path = os.path.basename(sys.modules['__main__'].__file__) - else: - main_path = None - data = pickle.dumps((target, args, kwargs)) - p = self._RemoteProcess(data, main_path) - if name is None: - temp = self._name.split('Host-')[-1] + '/Process-%s' - name = temp % ':'.join(map(str, p.get_identity())) - p.set_name(name) - return p - - @classmethod - def from_address(cls, address, authkey): - manager = cls(address, authkey) - managers.transact(address, authkey, 'dummy') - manager._state.value = managers.State.STARTED - manager._name = 'Host-%s:%s' % manager.address - manager.shutdown = util.Finalize( - manager, HostManager._finalize_host, - args=(manager._address, manager._authkey, manager._name), - exitpriority=-10 - ) - return manager - - @staticmethod - def _finalize_host(address, authkey, name): - managers.transact(address, authkey, 'shutdown') - - def __repr__(self): - return '' % self._name - -# -# Process subclass representing a process on (possibly) a remote machine -# - -class RemoteProcess(Process): - ''' - Represents a process started on a remote host - ''' - def __init__(self, data, main_path): - assert not main_path or os.path.basename(main_path) == main_path - Process.__init__(self) - self._data = data - self._main_path = main_path - - def _bootstrap(self): - forking.prepare({'main_path': self._main_path}) - self._target, self._args, self._kwargs = pickle.loads(self._data) - return Process._bootstrap(self) - - def get_identity(self): - return self._identity - -HostManager.register('_RemoteProcess', RemoteProcess) - -# -# A Pool class that uses a cluster -# - -class DistributedPool(pool.Pool): - - def __init__(self, cluster, processes=None, initializer=None, initargs=()): - self._cluster = cluster - self.Process = cluster.Process - pool.Pool.__init__(self, processes or len(cluster), - initializer, initargs) - - def _setup_queues(self): - self._inqueue = self._cluster._SettableQueue() - self._outqueue = self._cluster._SettableQueue() - self._quick_put = self._inqueue.put - self._quick_get = self._outqueue.get - - @staticmethod - def _help_stuff_finish(inqueue, task_handler, size): - inqueue.set_contents([None] * size) - -# -# Manager type which starts host managers on other machines -# - -def LocalProcess(**kwds): - p = Process(**kwds) - p.set_name('localhost/' + p.name) - return p - -class Cluster(managers.SyncManager): - ''' - Represents collection of slots running on various hosts. - - `Cluster` is a subclass of `SyncManager` so it allows creation of - various types of shared objects. - ''' - def __init__(self, hostlist, modules): - managers.SyncManager.__init__(self, address=('localhost', 0)) - self._hostlist = hostlist - self._modules = modules - if __name__ not in modules: - modules.append(__name__) - files = [sys.modules[name].__file__ for name in modules] - for i, file in enumerate(files): - if file.endswith('.pyc') or file.endswith('.pyo'): - files[i] = file[:-4] + '.py' - self._files = [os.path.abspath(file) for file in files] - - def start(self): - managers.SyncManager.start(self) - - l = connection.Listener(family='AF_INET', authkey=self._authkey) - - for i, host in enumerate(self._hostlist): - host._start_manager(i, self._authkey, l.address, self._files) - - for host in self._hostlist: - if host.hostname != 'localhost': - conn = l.accept() - i, address, cpus = conn.recv() - conn.close() - other_host = self._hostlist[i] - other_host.manager = HostManager.from_address(address, - self._authkey) - other_host.slots = other_host.slots or cpus - other_host.Process = other_host.manager.Process - else: - host.slots = host.slots or slot_count - host.Process = LocalProcess - - self._slotlist = [ - Slot(host) for host in self._hostlist for i in range(host.slots) - ] - self._slot_iterator = itertools.cycle(self._slotlist) - self._base_shutdown = self.shutdown - del self.shutdown - - def shutdown(self): - for host in self._hostlist: - if host.hostname != 'localhost': - host.manager.shutdown() - self._base_shutdown() - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - slot = self._slot_iterator.next() - return slot.Process( - group=group, target=target, name=name, args=args, kwargs=kwargs - ) - - def Pool(self, processes=None, initializer=None, initargs=()): - return DistributedPool(self, processes, initializer, initargs) - - def __getitem__(self, i): - return self._slotlist[i] - - def __len__(self): - return len(self._slotlist) - - def __iter__(self): - return iter(self._slotlist) - -# -# Queue subclass used by distributed pool -# - -class SettableQueue(Queue.Queue): - def empty(self): - return not self.queue - def full(self): - return self.maxsize > 0 and len(self.queue) == self.maxsize - def set_contents(self, contents): - # length of contents must be at least as large as the number of - # threads which have potentially called get() - self.not_empty.acquire() - try: - self.queue.clear() - self.queue.extend(contents) - self.not_empty.notifyAll() - finally: - self.not_empty.release() - -Cluster.register('_SettableQueue', SettableQueue) - -# -# Class representing a notional cpu in the cluster -# - -class Slot(object): - def __init__(self, host): - self.host = host - self.Process = host.Process - -# -# Host -# - -class Host(object): - ''' - Represents a host to use as a node in a cluster. - - `hostname` gives the name of the host. If hostname is not - "localhost" then ssh is used to log in to the host. To log in as - a different user use a host name of the form - "username at somewhere.org" - - `slots` is used to specify the number of slots for processes on - the host. This affects how often processes will be allocated to - this host. Normally this should be equal to the number of cpus on - that host. - ''' - def __init__(self, hostname, slots=None): - self.hostname = hostname - self.slots = slots - - def _start_manager(self, index, authkey, address, files): - if self.hostname != 'localhost': - tempdir = copy_to_remote_temporary_directory(self.hostname, files) - debug('startup files copied to %s:%s', self.hostname, tempdir) - p = subprocess.Popen( - ['ssh', self.hostname, 'python', '-c', - '"import os; os.chdir(%r); ' - 'from distributing import main; main()"' % tempdir], - stdin=subprocess.PIPE - ) - data = dict( - name='BoostrappingHost', index=index, - dist_log_level=_logger.getEffectiveLevel(), - dir=tempdir, authkey=str(authkey), parent_address=address - ) - pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL) - p.stdin.close() - -# -# Copy files to remote directory, returning name of directory -# - -unzip_code = '''" -import tempfile, os, sys, tarfile -tempdir = tempfile.mkdtemp(prefix='distrib-') -os.chdir(tempdir) -tf = tarfile.open(fileobj=sys.stdin, mode='r|gz') -for ti in tf: - tf.extract(ti) -print tempdir -"''' - -def copy_to_remote_temporary_directory(host, files): - p = subprocess.Popen( - ['ssh', host, 'python', '-c', unzip_code], - stdout=subprocess.PIPE, stdin=subprocess.PIPE - ) - tf = tarfile.open(fileobj=p.stdin, mode='w|gz') - for name in files: - tf.add(name, os.path.basename(name)) - tf.close() - p.stdin.close() - return p.stdout.read().rstrip() - -# -# Code which runs a host manager -# - -def main(): - # get data from parent over stdin - data = pickle.load(sys.stdin) - sys.stdin.close() - - # set some stuff - _logger.setLevel(data['dist_log_level']) - forking.prepare(data) - - # create server for a `HostManager` object - server = managers.Server(HostManager._registry, ('', 0), data['authkey']) - current_process()._server = server - - # report server address and number of cpus back to parent - conn = connection.Client(data['parent_address'], authkey=data['authkey']) - conn.send((data['index'], server.address, slot_count)) - conn.close() - - # set name etc - current_process().set_name('Host-%s:%s' % server.address) - util._run_after_forkers() - - # register a cleanup function - def cleanup(directory): - debug('removing directory %s', directory) - shutil.rmtree(directory) - debug('shutting down host manager') - util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0) - - # start host manager - debug('remote host manager starting in %s', data['dir']) - server.serve_forever() Modified: python/branches/release26-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release26-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release26-maint/Doc/library/multiprocessing.rst Sat Nov 21 15:23:46 2009 @@ -2220,10 +2220,3 @@ .. literalinclude:: ../includes/mp_benchmarks.py -An example/demo of how to use the :class:`managers.SyncManager`, :class:`Process` -and others to build a system which can distribute processes and work via a -distributed queue to a "cluster" of machines on a network, accessible via SSH. -You will need to have private key authentication for all hosts configured for -this to work. - -.. literalinclude:: ../includes/mp_distributing.py From jnoller at gmail.com Sat Nov 21 15:25:22 2009 From: jnoller at gmail.com (Jesse Noller) Date: Sat, 21 Nov 2009 09:25:22 -0500 Subject: [Python-checkins] r76433 - in python/trunk: Doc/includes/mp_distributing.py Doc/library/multiprocessing.rst Lib/multiprocessing/queues.py In-Reply-To: <4b07f307.0167f10a.09a7.ffff8bb8SMTPIN_ADDED@mx.google.com> References: <4b07f307.0167f10a.09a7.ffff8bb8SMTPIN_ADDED@mx.google.com> Message-ID: <4222a8490911210625g7d100549g764158f0157819e1@mail.gmail.com> Yes, I brain farted and pulled back in some debugging work I was in the middle of in the checkin, I reverted the queues.py change on trunk and removed it from the merges that followed. On Sat, Nov 21, 2009 at 9:02 AM, jesse.noller wrote: > Author: jesse.noller > Date: Sat Nov 21 15:01:56 2009 > New Revision: 76433 > > Log: > issue5738: The distribution example was confusing, and out of date. It's too large to include inline in the docs as well. It belongs in an addons module outside the stdlib. Removing. > > Removed: > ? python/trunk/Doc/includes/mp_distributing.py > Modified: > ? python/trunk/Doc/library/multiprocessing.rst > ? python/trunk/Lib/multiprocessing/queues.py > > Deleted: python/trunk/Doc/includes/mp_distributing.py > ============================================================================== > --- python/trunk/Doc/includes/mp_distributing.py ? ? ? ?Sat Nov 21 15:01:56 2009 > +++ (empty file) > @@ -1,364 +0,0 @@ > -# > -# Module to allow spawning of processes on foreign host > -# > -# Depends on `multiprocessing` package -- tested with `processing-0.60` > -# > -# Copyright (c) 2006-2008, R Oudkerk > -# All rights reserved. > -# > - > -__all__ = ['Cluster', 'Host', 'get_logger', 'current_process'] > - > -# > -# Imports > -# > - > -import sys > -import os > -import tarfile > -import shutil > -import subprocess > -import logging > -import itertools > -import Queue > - > -try: > - ? ?import cPickle as pickle > -except ImportError: > - ? ?import pickle > - > -from multiprocessing import Process, current_process, cpu_count > -from multiprocessing import util, managers, connection, forking, pool > - > -# > -# Logging > -# > - > -def get_logger(): > - ? ?return _logger > - > -_logger = logging.getLogger('distributing') > -_logger.propagate = 0 > - > -_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) > -_handler = logging.StreamHandler() > -_handler.setFormatter(_formatter) > -_logger.addHandler(_handler) > - > -info = _logger.info > -debug = _logger.debug > - > -# > -# Get number of cpus > -# > - > -try: > - ? ?slot_count = cpu_count() > -except NotImplemented: > - ? ?slot_count = 1 > - > -# > -# Manager type which spawns subprocesses > -# > - > -class HostManager(managers.SyncManager): > - ? ?''' > - ? ?Manager type used for spawning processes on a (presumably) foreign host > - ? ?''' > - ? ?def __init__(self, address, authkey): > - ? ? ? ?managers.SyncManager.__init__(self, address, authkey) > - ? ? ? ?self._name = 'Host-unknown' > - > - ? ?def Process(self, group=None, target=None, name=None, args=(), kwargs={}): > - ? ? ? ?if hasattr(sys.modules['__main__'], '__file__'): > - ? ? ? ? ? ?main_path = os.path.basename(sys.modules['__main__'].__file__) > - ? ? ? ?else: > - ? ? ? ? ? ?main_path = None > - ? ? ? ?data = pickle.dumps((target, args, kwargs)) > - ? ? ? ?p = self._RemoteProcess(data, main_path) > - ? ? ? ?if name is None: > - ? ? ? ? ? ?temp = self._name.split('Host-')[-1] + '/Process-%s' > - ? ? ? ? ? ?name = temp % ':'.join(map(str, p.get_identity())) > - ? ? ? ?p.set_name(name) > - ? ? ? ?return p > - > - ? ?@classmethod > - ? ?def from_address(cls, address, authkey): > - ? ? ? ?manager = cls(address, authkey) > - ? ? ? ?managers.transact(address, authkey, 'dummy') > - ? ? ? ?manager._state.value = managers.State.STARTED > - ? ? ? ?manager._name = 'Host-%s:%s' % manager.address > - ? ? ? ?manager.shutdown = util.Finalize( > - ? ? ? ? ? ?manager, HostManager._finalize_host, > - ? ? ? ? ? ?args=(manager._address, manager._authkey, manager._name), > - ? ? ? ? ? ?exitpriority=-10 > - ? ? ? ? ? ?) > - ? ? ? ?return manager > - > - ? ?@staticmethod > - ? ?def _finalize_host(address, authkey, name): > - ? ? ? ?managers.transact(address, authkey, 'shutdown') > - > - ? ?def __repr__(self): > - ? ? ? ?return '' % self._name > - > -# > -# Process subclass representing a process on (possibly) a remote machine > -# > - > -class RemoteProcess(Process): > - ? ?''' > - ? ?Represents a process started on a remote host > - ? ?''' > - ? ?def __init__(self, data, main_path): > - ? ? ? ?assert not main_path or os.path.basename(main_path) == main_path > - ? ? ? ?Process.__init__(self) > - ? ? ? ?self._data = data > - ? ? ? ?self._main_path = main_path > - > - ? ?def _bootstrap(self): > - ? ? ? ?forking.prepare({'main_path': self._main_path}) > - ? ? ? ?self._target, self._args, self._kwargs = pickle.loads(self._data) > - ? ? ? ?return Process._bootstrap(self) > - > - ? ?def get_identity(self): > - ? ? ? ?return self._identity > - > -HostManager.register('_RemoteProcess', RemoteProcess) > - > -# > -# A Pool class that uses a cluster > -# > - > -class DistributedPool(pool.Pool): > - > - ? ?def __init__(self, cluster, processes=None, initializer=None, initargs=()): > - ? ? ? ?self._cluster = cluster > - ? ? ? ?self.Process = cluster.Process > - ? ? ? ?pool.Pool.__init__(self, processes or len(cluster), > - ? ? ? ? ? ? ? ? ? ? ? ? ? initializer, initargs) > - > - ? ?def _setup_queues(self): > - ? ? ? ?self._inqueue = self._cluster._SettableQueue() > - ? ? ? ?self._outqueue = self._cluster._SettableQueue() > - ? ? ? ?self._quick_put = self._inqueue.put > - ? ? ? ?self._quick_get = self._outqueue.get > - > - ? ?@staticmethod > - ? ?def _help_stuff_finish(inqueue, task_handler, size): > - ? ? ? ?inqueue.set_contents([None] * size) > - > -# > -# Manager type which starts host managers on other machines > -# > - > -def LocalProcess(**kwds): > - ? ?p = Process(**kwds) > - ? ?p.set_name('localhost/' + p.name) > - ? ?return p > - > -class Cluster(managers.SyncManager): > - ? ?''' > - ? ?Represents collection of slots running on various hosts. > - > - ? ?`Cluster` is a subclass of `SyncManager` so it allows creation of > - ? ?various types of shared objects. > - ? ?''' > - ? ?def __init__(self, hostlist, modules): > - ? ? ? ?managers.SyncManager.__init__(self, address=('localhost', 0)) > - ? ? ? ?self._hostlist = hostlist > - ? ? ? ?self._modules = modules > - ? ? ? ?if __name__ not in modules: > - ? ? ? ? ? ?modules.append(__name__) > - ? ? ? ?files = [sys.modules[name].__file__ for name in modules] > - ? ? ? ?for i, file in enumerate(files): > - ? ? ? ? ? ?if file.endswith('.pyc') or file.endswith('.pyo'): > - ? ? ? ? ? ? ? ?files[i] = file[:-4] + '.py' > - ? ? ? ?self._files = [os.path.abspath(file) for file in files] > - > - ? ?def start(self): > - ? ? ? ?managers.SyncManager.start(self) > - > - ? ? ? ?l = connection.Listener(family='AF_INET', authkey=self._authkey) > - > - ? ? ? ?for i, host in enumerate(self._hostlist): > - ? ? ? ? ? ?host._start_manager(i, self._authkey, l.address, self._files) > - > - ? ? ? ?for host in self._hostlist: > - ? ? ? ? ? ?if host.hostname != 'localhost': > - ? ? ? ? ? ? ? ?conn = l.accept() > - ? ? ? ? ? ? ? ?i, address, cpus = conn.recv() > - ? ? ? ? ? ? ? ?conn.close() > - ? ? ? ? ? ? ? ?other_host = self._hostlist[i] > - ? ? ? ? ? ? ? ?other_host.manager = HostManager.from_address(address, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?self._authkey) > - ? ? ? ? ? ? ? ?other_host.slots = other_host.slots or cpus > - ? ? ? ? ? ? ? ?other_host.Process = other_host.manager.Process > - ? ? ? ? ? ?else: > - ? ? ? ? ? ? ? ?host.slots = host.slots or slot_count > - ? ? ? ? ? ? ? ?host.Process = LocalProcess > - > - ? ? ? ?self._slotlist = [ > - ? ? ? ? ? ?Slot(host) for host in self._hostlist for i in range(host.slots) > - ? ? ? ? ? ?] > - ? ? ? ?self._slot_iterator = itertools.cycle(self._slotlist) > - ? ? ? ?self._base_shutdown = self.shutdown > - ? ? ? ?del self.shutdown > - > - ? ?def shutdown(self): > - ? ? ? ?for host in self._hostlist: > - ? ? ? ? ? ?if host.hostname != 'localhost': > - ? ? ? ? ? ? ? ?host.manager.shutdown() > - ? ? ? ?self._base_shutdown() > - > - ? ?def Process(self, group=None, target=None, name=None, args=(), kwargs={}): > - ? ? ? ?slot = self._slot_iterator.next() > - ? ? ? ?return slot.Process( > - ? ? ? ? ? ?group=group, target=target, name=name, args=args, kwargs=kwargs > - ? ? ? ? ? ?) > - > - ? ?def Pool(self, processes=None, initializer=None, initargs=()): > - ? ? ? ?return DistributedPool(self, processes, initializer, initargs) > - > - ? ?def __getitem__(self, i): > - ? ? ? ?return self._slotlist[i] > - > - ? ?def __len__(self): > - ? ? ? ?return len(self._slotlist) > - > - ? ?def __iter__(self): > - ? ? ? ?return iter(self._slotlist) > - > -# > -# Queue subclass used by distributed pool > -# > - > -class SettableQueue(Queue.Queue): > - ? ?def empty(self): > - ? ? ? ?return not self.queue > - ? ?def full(self): > - ? ? ? ?return self.maxsize > 0 and len(self.queue) == self.maxsize > - ? ?def set_contents(self, contents): > - ? ? ? ?# length of contents must be at least as large as the number of > - ? ? ? ?# threads which have potentially called get() > - ? ? ? ?self.not_empty.acquire() > - ? ? ? ?try: > - ? ? ? ? ? ?self.queue.clear() > - ? ? ? ? ? ?self.queue.extend(contents) > - ? ? ? ? ? ?self.not_empty.notifyAll() > - ? ? ? ?finally: > - ? ? ? ? ? ?self.not_empty.release() > - > -Cluster.register('_SettableQueue', SettableQueue) > - > -# > -# Class representing a notional cpu in the cluster > -# > - > -class Slot(object): > - ? ?def __init__(self, host): > - ? ? ? ?self.host = host > - ? ? ? ?self.Process = host.Process > - > -# > -# Host > -# > - > -class Host(object): > - ? ?''' > - ? ?Represents a host to use as a node in a cluster. > - > - ? ?`hostname` gives the name of the host. ?If hostname is not > - ? ?"localhost" then ssh is used to log in to the host. ?To log in as > - ? ?a different user use a host name of the form > - ? ?"username at somewhere.org" > - > - ? ?`slots` is used to specify the number of slots for processes on > - ? ?the host. ?This affects how often processes will be allocated to > - ? ?this host. ?Normally this should be equal to the number of cpus on > - ? ?that host. > - ? ?''' > - ? ?def __init__(self, hostname, slots=None): > - ? ? ? ?self.hostname = hostname > - ? ? ? ?self.slots = slots > - > - ? ?def _start_manager(self, index, authkey, address, files): > - ? ? ? ?if self.hostname != 'localhost': > - ? ? ? ? ? ?tempdir = copy_to_remote_temporary_directory(self.hostname, files) > - ? ? ? ? ? ?debug('startup files copied to %s:%s', self.hostname, tempdir) > - ? ? ? ? ? ?p = subprocess.Popen( > - ? ? ? ? ? ? ? ?['ssh', self.hostname, 'python', '-c', > - ? ? ? ? ? ? ? ? '"import os; os.chdir(%r); ' > - ? ? ? ? ? ? ? ? 'from distributing import main; main()"' % tempdir], > - ? ? ? ? ? ? ? ?stdin=subprocess.PIPE > - ? ? ? ? ? ? ? ?) > - ? ? ? ? ? ?data = dict( > - ? ? ? ? ? ? ? ?name='BoostrappingHost', index=index, > - ? ? ? ? ? ? ? ?dist_log_level=_logger.getEffectiveLevel(), > - ? ? ? ? ? ? ? ?dir=tempdir, authkey=str(authkey), parent_address=address > - ? ? ? ? ? ? ? ?) > - ? ? ? ? ? ?pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL) > - ? ? ? ? ? ?p.stdin.close() > - > -# > -# Copy files to remote directory, returning name of directory > -# > - > -unzip_code = '''" > -import tempfile, os, sys, tarfile > -tempdir = tempfile.mkdtemp(prefix='distrib-') > -os.chdir(tempdir) > -tf = tarfile.open(fileobj=sys.stdin, mode='r|gz') > -for ti in tf: > - ? ?tf.extract(ti) > -print tempdir > -"''' > - > -def copy_to_remote_temporary_directory(host, files): > - ? ?p = subprocess.Popen( > - ? ? ? ?['ssh', host, 'python', '-c', unzip_code], > - ? ? ? ?stdout=subprocess.PIPE, stdin=subprocess.PIPE > - ? ? ? ?) > - ? ?tf = tarfile.open(fileobj=p.stdin, mode='w|gz') > - ? ?for name in files: > - ? ? ? ?tf.add(name, os.path.basename(name)) > - ? ?tf.close() > - ? ?p.stdin.close() > - ? ?return p.stdout.read().rstrip() > - > -# > -# Code which runs a host manager > -# > - > -def main(): > - ? ?# get data from parent over stdin > - ? ?data = pickle.load(sys.stdin) > - ? ?sys.stdin.close() > - > - ? ?# set some stuff > - ? ?_logger.setLevel(data['dist_log_level']) > - ? ?forking.prepare(data) > - > - ? ?# create server for a `HostManager` object > - ? ?server = managers.Server(HostManager._registry, ('', 0), data['authkey']) > - ? ?current_process()._server = server > - > - ? ?# report server address and number of cpus back to parent > - ? ?conn = connection.Client(data['parent_address'], authkey=data['authkey']) > - ? ?conn.send((data['index'], server.address, slot_count)) > - ? ?conn.close() > - > - ? ?# set name etc > - ? ?current_process().set_name('Host-%s:%s' % server.address) > - ? ?util._run_after_forkers() > - > - ? ?# register a cleanup function > - ? ?def cleanup(directory): > - ? ? ? ?debug('removing directory %s', directory) > - ? ? ? ?shutil.rmtree(directory) > - ? ? ? ?debug('shutting down host manager') > - ? ?util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0) > - > - ? ?# start host manager > - ? ?debug('remote host manager starting in %s', data['dir']) > - ? ?server.serve_forever() > > Modified: python/trunk/Doc/library/multiprocessing.rst > ============================================================================== > --- python/trunk/Doc/library/multiprocessing.rst ? ? ? ?(original) > +++ python/trunk/Doc/library/multiprocessing.rst ? ? ? ?Sat Nov 21 15:01:56 2009 > @@ -2230,10 +2230,3 @@ > > ?.. literalinclude:: ../includes/mp_benchmarks.py > > -An example/demo of how to use the :class:`managers.SyncManager`, :class:`Process` > -and others to build a system which can distribute processes and work via a > -distributed queue to a "cluster" of machines on a network, accessible via SSH. > -You will need to have private key authentication for all hosts configured for > -this to work. > - > -.. literalinclude:: ../includes/mp_distributing.py > > Modified: python/trunk/Lib/multiprocessing/queues.py > ============================================================================== > --- python/trunk/Lib/multiprocessing/queues.py ?(original) > +++ python/trunk/Lib/multiprocessing/queues.py ?Sat Nov 21 15:01:56 2009 > @@ -47,6 +47,8 @@ > ? ? ? ? if sys.platform != 'win32': > ? ? ? ? ? ? register_after_fork(self, Queue._after_fork) > > + ? ? ? ?self.getv = 0 > + > ? ? def __getstate__(self): > ? ? ? ? assert_spawning(self) > ? ? ? ? return (self._maxsize, self._reader, self._writer, > @@ -71,6 +73,8 @@ > ? ? ? ? self._poll = self._reader.poll > > ? ? def put(self, obj, block=True, timeout=None): > + ? ? ? ?if not isinstance(obj, list): > + ? ? ? ? ? ?debug('put: %s', obj) > ? ? ? ? assert not self._closed > ? ? ? ? if not self._sem.acquire(block, timeout): > ? ? ? ? ? ? raise Full > @@ -85,11 +89,15 @@ > ? ? ? ? ? ? self._notempty.release() > > ? ? def get(self, block=True, timeout=None): > + ? ? ? ?self.getv += 1 > + ? ? ? ?debug('self.getv: %s', self.getv) > ? ? ? ? if block and timeout is None: > ? ? ? ? ? ? self._rlock.acquire() > ? ? ? ? ? ? try: > ? ? ? ? ? ? ? ? res = self._recv() > ? ? ? ? ? ? ? ? self._sem.release() > + ? ? ? ? ? ? ? ?if not isinstance(res, list): > + ? ? ? ? ? ? ? ? ? ?debug('get: %s', res) > ? ? ? ? ? ? ? ? return res > ? ? ? ? ? ? finally: > ? ? ? ? ? ? ? ? self._rlock.release() > @@ -104,6 +112,8 @@ > ? ? ? ? ? ? ? ? ? ? raise Empty > ? ? ? ? ? ? ? ? res = self._recv() > ? ? ? ? ? ? ? ? self._sem.release() > + ? ? ? ? ? ? ? ?if not isinstance(res, list): > + ? ? ? ? ? ? ? ? ? ?debug('get: %s', res) > ? ? ? ? ? ? ? ? return res > ? ? ? ? ? ? finally: > ? ? ? ? ? ? ? ? self._rlock.release() > @@ -229,16 +239,22 @@ > ? ? ? ? ? ? ? ? try: > ? ? ? ? ? ? ? ? ? ? while 1: > ? ? ? ? ? ? ? ? ? ? ? ? obj = bpopleft() > + ? ? ? ? ? ? ? ? ? ? ? ?if not isinstance(obj, list): > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?debug('feeder thread got: %s', obj) > ? ? ? ? ? ? ? ? ? ? ? ? if obj is sentinel: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? debug('feeder thread got sentinel -- exiting') > ? ? ? ? ? ? ? ? ? ? ? ? ? ? close() > ? ? ? ? ? ? ? ? ? ? ? ? ? ? return > - > ? ? ? ? ? ? ? ? ? ? ? ? if wacquire is None: > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?if not isinstance(obj, list): > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?debug('sending to pipe: %s', obj) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? send(obj) > ? ? ? ? ? ? ? ? ? ? ? ? else: > - ? ? ? ? ? ? ? ? ? ? ? ? ? ?wacquire() > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?debug('waiting on wacquire') > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?wacquire(timeout=30) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? try: > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if not isinstance(obj, list): > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?debug('sending to pipe: %s', obj) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? send(obj) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? finally: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? wrelease() > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Sat Nov 21 15:28:40 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 14:28:40 -0000 Subject: [Python-checkins] r76437 - in python/branches/release31-maint: Doc/includes/mp_distributing.py Doc/library/multiprocessing.rst Message-ID: Author: jesse.noller Date: Sat Nov 21 15:28:39 2009 New Revision: 76437 Log: Merged revisions 76435 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76435 | jesse.noller | 2009-11-21 09:20:14 -0500 (Sat, 21 Nov 2009) | 9 lines Merged revisions 76433 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76433 | jesse.noller | 2009-11-21 09:01:56 -0500 (Sat, 21 Nov 2009) | 1 line issue5738: The distribution example was confusing, and out of date. It's too large to include inline in the docs as well. It belongs in an addons module outside the stdlib. Removing. ........ ................ Removed: python/branches/release31-maint/Doc/includes/mp_distributing.py Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/multiprocessing.rst Deleted: python/branches/release31-maint/Doc/includes/mp_distributing.py ============================================================================== --- python/branches/release31-maint/Doc/includes/mp_distributing.py Sat Nov 21 15:28:39 2009 +++ (empty file) @@ -1,364 +0,0 @@ -# -# Module to allow spawning of processes on foreign host -# -# Depends on `multiprocessing` package -- tested with `processing-0.60` -# -# Copyright (c) 2006-2008, R Oudkerk -# All rights reserved. -# - -__all__ = ['Cluster', 'Host', 'get_logger', 'current_process'] - -# -# Imports -# - -import sys -import os -import tarfile -import shutil -import subprocess -import logging -import itertools -import queue - -try: - import pickle as pickle -except ImportError: - import pickle - -from multiprocessing import Process, current_process, cpu_count -from multiprocessing import util, managers, connection, forking, pool - -# -# Logging -# - -def get_logger(): - return _logger - -_logger = logging.getLogger('distributing') -_logger.propagate = 0 - -_formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) -_handler = logging.StreamHandler() -_handler.setFormatter(_formatter) -_logger.addHandler(_handler) - -info = _logger.info -debug = _logger.debug - -# -# Get number of cpus -# - -try: - slot_count = cpu_count() -except NotImplemented: - slot_count = 1 - -# -# Manager type which spawns subprocesses -# - -class HostManager(managers.SyncManager): - ''' - Manager type used for spawning processes on a (presumably) foreign host - ''' - def __init__(self, address, authkey): - managers.SyncManager.__init__(self, address, authkey) - self._name = 'Host-unknown' - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - if hasattr(sys.modules['__main__'], '__file__'): - main_path = os.path.basename(sys.modules['__main__'].__file__) - else: - main_path = None - data = pickle.dumps((target, args, kwargs)) - p = self._RemoteProcess(data, main_path) - if name is None: - temp = self._name.split('Host-')[-1] + '/Process-%s' - name = temp % ':'.join(map(str, p.get_identity())) - p.set_name(name) - return p - - @classmethod - def from_address(cls, address, authkey): - manager = cls(address, authkey) - managers.transact(address, authkey, 'dummy') - manager._state.value = managers.State.STARTED - manager._name = 'Host-%s:%s' % manager.address - manager.shutdown = util.Finalize( - manager, HostManager._finalize_host, - args=(manager._address, manager._authkey, manager._name), - exitpriority=-10 - ) - return manager - - @staticmethod - def _finalize_host(address, authkey, name): - managers.transact(address, authkey, 'shutdown') - - def __repr__(self): - return '' % self._name - -# -# Process subclass representing a process on (possibly) a remote machine -# - -class RemoteProcess(Process): - ''' - Represents a process started on a remote host - ''' - def __init__(self, data, main_path): - assert not main_path or os.path.basename(main_path) == main_path - Process.__init__(self) - self._data = data - self._main_path = main_path - - def _bootstrap(self): - forking.prepare({'main_path': self._main_path}) - self._target, self._args, self._kwargs = pickle.loads(self._data) - return Process._bootstrap(self) - - def get_identity(self): - return self._identity - -HostManager.register('_RemoteProcess', RemoteProcess) - -# -# A Pool class that uses a cluster -# - -class DistributedPool(pool.Pool): - - def __init__(self, cluster, processes=None, initializer=None, initargs=()): - self._cluster = cluster - self.Process = cluster.Process - pool.Pool.__init__(self, processes or len(cluster), - initializer, initargs) - - def _setup_queues(self): - self._inqueue = self._cluster._SettableQueue() - self._outqueue = self._cluster._SettableQueue() - self._quick_put = self._inqueue.put - self._quick_get = self._outqueue.get - - @staticmethod - def _help_stuff_finish(inqueue, task_handler, size): - inqueue.set_contents([None] * size) - -# -# Manager type which starts host managers on other machines -# - -def LocalProcess(**kwds): - p = Process(**kwds) - p.set_name('localhost/' + p.name) - return p - -class Cluster(managers.SyncManager): - ''' - Represents collection of slots running on various hosts. - - `Cluster` is a subclass of `SyncManager` so it allows creation of - various types of shared objects. - ''' - def __init__(self, hostlist, modules): - managers.SyncManager.__init__(self, address=('localhost', 0)) - self._hostlist = hostlist - self._modules = modules - if __name__ not in modules: - modules.append(__name__) - files = [sys.modules[name].__file__ for name in modules] - for i, file in enumerate(files): - if file.endswith('.pyc') or file.endswith('.pyo'): - files[i] = file[:-4] + '.py' - self._files = [os.path.abspath(file) for file in files] - - def start(self): - managers.SyncManager.start(self) - - l = connection.Listener(family='AF_INET', authkey=self._authkey) - - for i, host in enumerate(self._hostlist): - host._start_manager(i, self._authkey, l.address, self._files) - - for host in self._hostlist: - if host.hostname != 'localhost': - conn = l.accept() - i, address, cpus = conn.recv() - conn.close() - other_host = self._hostlist[i] - other_host.manager = HostManager.from_address(address, - self._authkey) - other_host.slots = other_host.slots or cpus - other_host.Process = other_host.manager.Process - else: - host.slots = host.slots or slot_count - host.Process = LocalProcess - - self._slotlist = [ - Slot(host) for host in self._hostlist for i in range(host.slots) - ] - self._slot_iterator = itertools.cycle(self._slotlist) - self._base_shutdown = self.shutdown - del self.shutdown - - def shutdown(self): - for host in self._hostlist: - if host.hostname != 'localhost': - host.manager.shutdown() - self._base_shutdown() - - def Process(self, group=None, target=None, name=None, args=(), kwargs={}): - slot = next(self._slot_iterator) - return slot.Process( - group=group, target=target, name=name, args=args, kwargs=kwargs - ) - - def Pool(self, processes=None, initializer=None, initargs=()): - return DistributedPool(self, processes, initializer, initargs) - - def __getitem__(self, i): - return self._slotlist[i] - - def __len__(self): - return len(self._slotlist) - - def __iter__(self): - return iter(self._slotlist) - -# -# Queue subclass used by distributed pool -# - -class SettableQueue(queue.Queue): - def empty(self): - return not self.queue - def full(self): - return self.maxsize > 0 and len(self.queue) == self.maxsize - def set_contents(self, contents): - # length of contents must be at least as large as the number of - # threads which have potentially called get() - self.not_empty.acquire() - try: - self.queue.clear() - self.queue.extend(contents) - self.not_empty.notifyAll() - finally: - self.not_empty.release() - -Cluster.register('_SettableQueue', SettableQueue) - -# -# Class representing a notional cpu in the cluster -# - -class Slot(object): - def __init__(self, host): - self.host = host - self.Process = host.Process - -# -# Host -# - -class Host(object): - ''' - Represents a host to use as a node in a cluster. - - `hostname` gives the name of the host. If hostname is not - "localhost" then ssh is used to log in to the host. To log in as - a different user use a host name of the form - "username at somewhere.org" - - `slots` is used to specify the number of slots for processes on - the host. This affects how often processes will be allocated to - this host. Normally this should be equal to the number of cpus on - that host. - ''' - def __init__(self, hostname, slots=None): - self.hostname = hostname - self.slots = slots - - def _start_manager(self, index, authkey, address, files): - if self.hostname != 'localhost': - tempdir = copy_to_remote_temporary_directory(self.hostname, files) - debug('startup files copied to %s:%s', self.hostname, tempdir) - p = subprocess.Popen( - ['ssh', self.hostname, 'python', '-c', - '"import os; os.chdir(%r); ' - 'from distributing import main; main()"' % tempdir], - stdin=subprocess.PIPE - ) - data = dict( - name='BoostrappingHost', index=index, - dist_log_level=_logger.getEffectiveLevel(), - dir=tempdir, authkey=str(authkey), parent_address=address - ) - pickle.dump(data, p.stdin, pickle.HIGHEST_PROTOCOL) - p.stdin.close() - -# -# Copy files to remote directory, returning name of directory -# - -unzip_code = '''" -import tempfile, os, sys, tarfile -tempdir = tempfile.mkdtemp(prefix='distrib-') -os.chdir(tempdir) -tf = tarfile.open(fileobj=sys.stdin, mode='r|gz') -for ti in tf: - tf.extract(ti) -print tempdir -"''' - -def copy_to_remote_temporary_directory(host, files): - p = subprocess.Popen( - ['ssh', host, 'python', '-c', unzip_code], - stdout=subprocess.PIPE, stdin=subprocess.PIPE - ) - tf = tarfile.open(fileobj=p.stdin, mode='w|gz') - for name in files: - tf.add(name, os.path.basename(name)) - tf.close() - p.stdin.close() - return p.stdout.read().rstrip() - -# -# Code which runs a host manager -# - -def main(): - # get data from parent over stdin - data = pickle.load(sys.stdin) - sys.stdin.close() - - # set some stuff - _logger.setLevel(data['dist_log_level']) - forking.prepare(data) - - # create server for a `HostManager` object - server = managers.Server(HostManager._registry, ('', 0), data['authkey']) - current_process()._server = server - - # report server address and number of cpus back to parent - conn = connection.Client(data['parent_address'], authkey=data['authkey']) - conn.send((data['index'], server.address, slot_count)) - conn.close() - - # set name etc - current_process().set_name('Host-%s:%s' % server.address) - util._run_after_forkers() - - # register a cleanup function - def cleanup(directory): - debug('removing directory %s', directory) - shutil.rmtree(directory) - debug('shutting down host manager') - util.Finalize(None, cleanup, args=[data['dir']], exitpriority=0) - - # start host manager - debug('remote host manager starting in %s', data['dir']) - server.serve_forever() Modified: python/branches/release31-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release31-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release31-maint/Doc/library/multiprocessing.rst Sat Nov 21 15:28:39 2009 @@ -2228,10 +2228,3 @@ .. literalinclude:: ../includes/mp_benchmarks.py -An example/demo of how to use the :class:`managers.SyncManager`, :class:`Process` -and others to build a system which can distribute processes and work via a -distributed queue to a "cluster" of machines on a network, accessible via SSH. -You will need to have private key authentication for all hosts configured for -this to work. - -.. literalinclude:: ../includes/mp_distributing.py From python-checkins at python.org Sat Nov 21 15:38:24 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 14:38:24 -0000 Subject: [Python-checkins] r76438 - python/trunk/Lib/test/test_multiprocessing.py Message-ID: Author: jesse.noller Date: Sat Nov 21 15:38:23 2009 New Revision: 76438 Log: issue6615: Additional test for logging support in multiprocessing Modified: python/trunk/Lib/test/test_multiprocessing.py Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Sat Nov 21 15:38:23 2009 @@ -1722,6 +1722,26 @@ root_logger.setLevel(root_level) logger.setLevel(level=LOG_LEVEL) + +class _TestLoggingProcessName(BaseTestCase): + + def handle(self, record): + assert record.processName == multiprocessing.current_process().name + self.__handled = True + + def test_logging(self): + handler = logging.Handler() + handler.handle = self.handle + self.__handled = False + # Bypass getLogger() and side-effects + logger = logging.getLoggerClass()( + 'multiprocessing.test.TestLoggingProcessName') + logger.addHandler(handler) + logger.propagate = False + + logger.warn('foo') + assert self.__handled + # # Test to verify handle verification, see issue 3321 # From python-checkins at python.org Sat Nov 21 19:09:38 2009 From: python-checkins at python.org (jesse.noller) Date: Sat, 21 Nov 2009 18:09:38 -0000 Subject: [Python-checkins] r76439 - in python/branches/py3k: Lib/test/test_multiprocessing.py Message-ID: Author: jesse.noller Date: Sat Nov 21 19:09:38 2009 New Revision: 76439 Log: Merged revisions 76438 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76438 | jesse.noller | 2009-11-21 09:38:23 -0500 (Sat, 21 Nov 2009) | 1 line issue6615: Additional test for logging support in multiprocessing ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_multiprocessing.py Modified: python/branches/py3k/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k/Lib/test/test_multiprocessing.py Sat Nov 21 19:09:38 2009 @@ -1723,6 +1723,26 @@ root_logger.setLevel(root_level) logger.setLevel(level=LOG_LEVEL) + +class _TestLoggingProcessName(BaseTestCase): + + def handle(self, record): + assert record.processName == multiprocessing.current_process().name + self.__handled = True + + def test_logging(self): + handler = logging.Handler() + handler.handle = self.handle + self.__handled = False + # Bypass getLogger() and side-effects + logger = logging.getLoggerClass()( + 'multiprocessing.test.TestLoggingProcessName') + logger.addHandler(handler) + logger.propagate = False + + logger.warn('foo') + assert self.__handled + # # Test to verify handle verification, see issue 3321 # From nnorwitz at gmail.com Sat Nov 21 22:24:37 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 21 Nov 2009 16:24:37 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091121212437.GA2252@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:651: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1984: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [876669 refs] From nnorwitz at gmail.com Sat Nov 21 23:51:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 21 Nov 2009 17:51:45 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091121225145.GA1826@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_itertools leaked [32, 0, 0] references, sum=32 test_ssl leaked [0, 0, 339] references, sum=339 Less important issues: ---------------------- From solipsis at pitrou.net Sun Nov 22 00:47:15 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 22 Nov 2009 00:47:15 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76439): sum=701 Message-ID: <20091121234715.799ED17720@ns6635.ovh.net> py3k results for svn r76439 (hg cset 7a7c486df1f7) -------------------------------------------------- test_multiprocessing leaked [229, 229, 229] references, sum=687 test_urllib leaked [6, 4, 4] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogbY4Rfb', '-x', 'test_httpservers'] From python-checkins at python.org Sun Nov 22 00:54:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2009 23:54:32 -0000 Subject: [Python-checkins] r76440 - python/branches/py3k/Doc/tools/sphinxext/indexsidebar.html Message-ID: Author: benjamin.peterson Date: Sun Nov 22 00:54:32 2009 New Revision: 76440 Log: don't say that 3.2 is another version Modified: python/branches/py3k/Doc/tools/sphinxext/indexsidebar.html Modified: python/branches/py3k/Doc/tools/sphinxext/indexsidebar.html ============================================================================== --- python/branches/py3k/Doc/tools/sphinxext/indexsidebar.html (original) +++ python/branches/py3k/Doc/tools/sphinxext/indexsidebar.html Sun Nov 22 00:54:32 2009 @@ -5,7 +5,6 @@
  • Python 2.6 (stable)
  • Python 2.7 (in development)
  • Python 3.1 (stable)
  • -
  • Python 3.2 (in development)
  • Old versions
  • From python-checkins at python.org Sun Nov 22 00:56:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2009 23:56:56 -0000 Subject: [Python-checkins] r76441 - python/branches/release31-maint/Doc/tools/sphinxext/indexsidebar.html Message-ID: Author: benjamin.peterson Date: Sun Nov 22 00:56:56 2009 New Revision: 76441 Log: remove 3.1 link Modified: python/branches/release31-maint/Doc/tools/sphinxext/indexsidebar.html Modified: python/branches/release31-maint/Doc/tools/sphinxext/indexsidebar.html ============================================================================== --- python/branches/release31-maint/Doc/tools/sphinxext/indexsidebar.html (original) +++ python/branches/release31-maint/Doc/tools/sphinxext/indexsidebar.html Sun Nov 22 00:56:56 2009 @@ -4,7 +4,6 @@ From nnorwitz at gmail.com Sun Nov 22 10:24:44 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 22 Nov 2009 04:24:44 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091122092444.GA32328@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:651: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:1984: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [876666 refs] From nnorwitz at gmail.com Sun Nov 22 11:51:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 22 Nov 2009 05:51:55 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091122105155.GA31903@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 0, 84] references, sum=84 Less important issues: ---------------------- From python-checkins at python.org Sun Nov 22 16:36:11 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 22 Nov 2009 15:36:11 -0000 Subject: [Python-checkins] r76442 - in python/branches/tarek_sysconfig/Lib: distutils/sysconfig.py distutils/tests/test_build_ext.py distutils/tests/test_build_scripts.py distutils/tests/test_util.py distutils/util.py site.py sysconfig.py test/test_site.py Message-ID: Author: tarek.ziade Date: Sun Nov 22 16:36:10 2009 New Revision: 76442 Log: added deprecation warnings, and make distutils and site use the new module Modified: python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_scripts.py python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py python/branches/tarek_sysconfig/Lib/distutils/util.py python/branches/tarek_sysconfig/Lib/site.py python/branches/tarek_sysconfig/Lib/sysconfig.py python/branches/tarek_sysconfig/Lib/test/test_site.py Modified: python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py Sun Nov 22 16:36:10 2009 @@ -14,149 +14,16 @@ import os import re import sys +from warnings import warn -from distutils.errors import DistutilsPlatformError +# importing sysconfig from Lib +# to avoid this module to shadow it +_sysconfig = __import__('sysconfig') # These are needed in a couple of spots, so just compute them once. PREFIX = os.path.normpath(sys.prefix) EXEC_PREFIX = os.path.normpath(sys.exec_prefix) -# Path to the base directory of the project. On Windows the binary may -# live in project/PCBuild9. If we're dealing with an x64 Windows build, -# it'll live in project/PCbuild/amd64. -project_base = os.path.dirname(os.path.abspath(sys.executable)) -if os.name == "nt" and "pcbuild" in project_base[-8:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir)) -# PC/VS7.1 -if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, - os.path.pardir)) -# PC/AMD64 -if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, - os.path.pardir)) - -# python_build: (Boolean) if true, we're either building Python or -# building an extension with an un-installed Python, so we use -# different (hard-wired) directories. -# Setup.local is available for Makefile builds including VPATH builds, -# Setup.dist is available on Windows -def _python_build(): - for fn in ("Setup.dist", "Setup.local"): - if os.path.isfile(os.path.join(project_base, "Modules", fn)): - return True - return False -python_build = _python_build() - - -def get_python_version(): - """Return a string containing the major and minor Python version, - leaving off the patchlevel. Sample return values could be '1.5' - or '2.2'. - """ - return sys.version[:3] - - -def get_python_inc(plat_specific=0, prefix=None): - """Return the directory containing installed Python header files. - - If 'plat_specific' is false (the default), this is the path to the - non-platform-specific header files, i.e. Python.h and so on; - otherwise, this is the path to platform-specific header files - (namely pyconfig.h). - - If 'prefix' is supplied, use it instead of sys.prefix or - sys.exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - prefix = plat_specific and EXEC_PREFIX or PREFIX - if os.name == "posix": - if python_build: - # Assume the executable is in the build directory. The - # pyconfig.h file should be in the same directory. Since - # the build directory may not be the source directory, we - # must use "srcdir" from the makefile to find the "Include" - # directory. - base = os.path.dirname(os.path.abspath(sys.executable)) - if plat_specific: - return base - else: - incdir = os.path.join(get_config_var('srcdir'), 'Include') - return os.path.normpath(incdir) - return os.path.join(prefix, "include", "python" + get_python_version()) - elif os.name == "nt": - return os.path.join(prefix, "include") - elif os.name == "mac": - if plat_specific: - return os.path.join(prefix, "Mac", "Include") - else: - return os.path.join(prefix, "Include") - elif os.name == "os2": - return os.path.join(prefix, "Include") - else: - raise DistutilsPlatformError( - "I don't know where Python installs its C header files " - "on platform '%s'" % os.name) - - -def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - """Return the directory containing the Python library (standard or - site additions). - - If 'plat_specific' is true, return the directory containing - platform-specific modules, i.e. any module from a non-pure-Python - module distribution; otherwise, return the platform-shared library - directory. If 'standard_lib' is true, return the directory - containing standard Python library modules; otherwise, return the - directory for site-specific modules. - - If 'prefix' is supplied, use it instead of sys.prefix or - sys.exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - prefix = plat_specific and EXEC_PREFIX or PREFIX - - if os.name == "posix": - libpython = os.path.join(prefix, - "lib", "python" + get_python_version()) - if standard_lib: - return libpython - else: - return os.path.join(libpython, "site-packages") - - elif os.name == "nt": - if standard_lib: - return os.path.join(prefix, "Lib") - else: - if get_python_version() < "2.2": - return prefix - else: - return os.path.join(prefix, "Lib", "site-packages") - - elif os.name == "mac": - if plat_specific: - if standard_lib: - return os.path.join(prefix, "Lib", "lib-dynload") - else: - return os.path.join(prefix, "Lib", "site-packages") - else: - if standard_lib: - return os.path.join(prefix, "Lib") - else: - return os.path.join(prefix, "Lib", "site-packages") - - elif os.name == "os2": - if standard_lib: - return os.path.join(prefix, "Lib") - else: - return os.path.join(prefix, "Lib", "site-packages") - - else: - raise DistutilsPlatformError( - "I don't know where Python installs its library " - "on platform '%s'" % os.name) - - def customize_compiler(compiler): """Do any platform-specific customization of a CCompiler instance. @@ -206,60 +73,131 @@ compiler.shared_lib_extension = so_ext +# +# The rest of this module is deprecated. will go away +# in Python 2.8/3.3 +# +class _DeprecatedString(str): + pass + # XXX how do I send a deprecation warning here ?? + +def _get_project_base(): + return _DeprecatedString(_sysconfig._PROJECT_BASE) + +project_base = _get_project_base() + +class _DeprecatedBool(int): + pass + # XXX how do I send a deprecation warning here ?? -def get_config_h_filename(): - """Return full pathname of installed pyconfig.h file.""" - if python_build: - if os.name == "nt": - inc_dir = os.path.join(project_base, "PC") - else: - inc_dir = project_base +def _python_build(): + return _DeprecatedBool(_sysconfig._PYTHON_BUILD) + +python_build = _python_build() + +_DEPRECATION_MSG = ("distutils.sysconfig.%s is deprecated. " + "Use the APIs provided by the sysconfig module instead") + +def get_python_version(): + """This function is deprecated. + + Return a string containing the major and minor Python version, + leaving off the patchlevel. Sample return values could be '1.5' + or '2.2'. + """ + warn(_DEPRECATION_MSG % 'get_python_version', DeprecationWarning) + return _sysconfig.get_python_version() + +def get_python_inc(plat_specific=0, prefix=None): + """This function is deprecated. + + Return the directory containing installed Python header files. + + If 'plat_specific' is false (the default), this is the path to the + non-platform-specific header files, i.e. Python.h and so on; + otherwise, this is the path to platform-specific header files + (namely pyconfig.h). + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + warn(_DEPRECATION_MSG % 'get_python_inc', DeprecationWarning) + get_path = _sysconfig.get_path + + if prefix is not None: + vars = {'base': prefix} + return get_path('include', vars=vars) + + if plat_specific: + return get_path('include') else: - inc_dir = get_python_inc(plat_specific=1) - if get_python_version() < '2.2': - config_h = 'config.h' + return get_path('platinclude') + +def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + """This function is deprecated. + + Return the directory containing the Python library (standard or + site additions). + + If 'plat_specific' is true, return the directory containing + platform-specific modules, i.e. any module from a non-pure-Python + module distribution; otherwise, return the platform-shared library + directory. If 'standard_lib' is true, return the directory + containing standard Python library modules; otherwise, return the + directory for site-specific modules. + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + warn(_DEPRECATION_MSG % 'get_python_lib', DeprecationWarning) + + # XXX deprecation warning + vars = {} + get_path = _sysconfig.get_path + if prefix is not None: + if plat_specific: + vars['platbase'] = prefix + else: + vars['base'] = prefix + + if standard_lib: + if plat_specific: + return get_path('platstdlib', vars=vars) + else: + return get_path('stdlib', vars=vars) else: - # The name of the config.h file changed in 2.2 - config_h = 'pyconfig.h' - return os.path.join(inc_dir, config_h) + if plat_specific: + return get_path('platib', vars=vars) + else: + return get_path('purelib', vars=vars) +def get_config_h_filename(): + """This function is deprecated. + + Return full pathname of installed pyconfig.h file. + """ + warn(_DEPRECATION_MSG % 'get_config_h_filename', DeprecationWarning) + return _sysconfig._get_config_h_filename() def get_makefile_filename(): - """Return full pathname of installed Makefile from the Python build.""" - if python_build: - return os.path.join(os.path.dirname(sys.executable), "Makefile") - lib_dir = get_python_lib(plat_specific=1, standard_lib=1) - return os.path.join(lib_dir, "config", "Makefile") + """This function is deprecated. + Return full pathname of installed Makefile from the Python build. + """ + warn(_DEPRECATION_MSG % 'get_makefile_filename', DeprecationWarning) + return _sysconfig._get_makefile_filename() def parse_config_h(fp, g=None): - """Parse a config.h-style file. + """This function is deprecated. + + Parse a config.h-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ - if g is None: - g = {} - define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") - # - while 1: - line = fp.readline() - if not line: - break - m = define_rx.match(line) - if m: - n, v = m.group(1, 2) - try: v = int(v) - except ValueError: pass - g[n] = v - else: - m = undef_rx.match(line) - if m: - g[m.group(1)] = 0 - return g - + warn(_DEPRECATION_MSG % 'parse_config_h', DeprecationWarning) + return _sysconfig._parse_config_h(fp, g) # Regexes needed for parsing Makefile (and similar syntaxes, # like old-style Setup files). @@ -268,91 +206,29 @@ _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") def parse_makefile(fn, g=None): - """Parse a Makefile-style file. + """This function is deprecated. + + Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ - from distutils.text_file import TextFile - fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1) - - if g is None: - g = {} - done = {} - notdone = {} - - while 1: - line = fp.readline() - if line is None: # eof - break - m = _variable_rx.match(line) - if m: - n, v = m.group(1, 2) - v = v.strip() - # `$$' is a literal `$' in make - tmpv = v.replace('$$', '') - - if "$" in tmpv: - notdone[n] = v - else: - try: - v = int(v) - except ValueError: - # insert literal `$' - done[n] = v.replace('$$', '$') - else: - done[n] = v - - # do variable interpolation here - while notdone: - for name in notdone.keys(): - value = notdone[name] - m = _findvar1_rx.search(value) or _findvar2_rx.search(value) - if m: - n = m.group(1) - found = True - if n in done: - item = str(done[n]) - elif n in notdone: - # get it on a subsequent round - found = False - elif n in os.environ: - # do it like make: fall back to environment - item = os.environ[n] - else: - done[n] = item = "" - if found: - after = value[m.end():] - value = value[:m.start()] + item + after - if "$" in after: - notdone[name] = value - else: - try: value = int(value) - except ValueError: - done[name] = value.strip() - else: - done[name] = value - del notdone[name] - else: - # bogus variable reference; just drop it since we can't deal - del notdone[name] - - fp.close() - - # save the results in the global dictionary - g.update(done) - return g - + warn(_DEPRECATION_MSG % 'parse_makefile', DeprecationWarning) + return _sysconfig._parse_makefile(fn, g) def expand_makefile_vars(s, vars): - """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + """This function is deprecated. + + Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in 'string' according to 'vars' (a dictionary mapping variable names to values). Variables not present in 'vars' are silently expanded to the empty string. The variable values in 'vars' should not contain further variable expansions; if 'vars' is the output of 'parse_makefile()', you're fine. Returns a variable-expanded version of 's'. """ + warn('this function will be removed in then next version of Python', + DeprecationWarning) # This algorithm does multiple expansion, so if vars['foo'] contains # "${bar}", it will expand ${foo} to ${bar}, and then expand @@ -369,152 +245,10 @@ break return s - -_config_vars = None - -def _init_posix(): - """Initialize the module as appropriate for POSIX systems.""" - g = {} - # load the installed Makefile: - try: - filename = get_makefile_filename() - parse_makefile(filename, g) - except IOError, msg: - my_msg = "invalid Python installation: unable to open %s" % filename - if hasattr(msg, "strerror"): - my_msg = my_msg + " (%s)" % msg.strerror - - raise DistutilsPlatformError(my_msg) - - # load the installed pyconfig.h: - try: - filename = get_config_h_filename() - parse_config_h(file(filename), g) - except IOError, msg: - my_msg = "invalid Python installation: unable to open %s" % filename - if hasattr(msg, "strerror"): - my_msg = my_msg + " (%s)" % msg.strerror - - raise DistutilsPlatformError(my_msg) - - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target) - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - - # On AIX, there are wrong paths to the linker scripts in the Makefile - # -- these paths are relative to the Python source, but when installed - # the scripts are in another directory. - if python_build: - g['LDSHARED'] = g['BLDSHARED'] - - elif get_python_version() < '2.1': - # The following two branches are for 1.5.2 compatibility. - if sys.platform == 'aix4': # what about AIX 3.x ? - # Linker script is in the config directory, not in Modules as the - # Makefile says. - python_lib = get_python_lib(standard_lib=1) - ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') - python_exp = os.path.join(python_lib, 'config', 'python.exp') - - g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) - - elif sys.platform == 'beos': - # Linker script is in the config directory. In the Makefile it is - # relative to the srcdir, which after installation no longer makes - # sense. - python_lib = get_python_lib(standard_lib=1) - linkerscript_path = g['LDSHARED'].split()[0] - linkerscript_name = os.path.basename(linkerscript_path) - linkerscript = os.path.join(python_lib, 'config', - linkerscript_name) - - # XXX this isn't the right place to do this: adding the Python - # library to the link, if needed, should be in the "build_ext" - # command. (It's also needed for non-MS compilers on Windows, and - # it's taken care of for them by the 'build_ext.get_libraries()' - # method.) - g['LDSHARED'] = ("%s -L%s/lib -lpython%s" % - (linkerscript, PREFIX, get_python_version())) - - global _config_vars - _config_vars = g - - -def _init_nt(): - """Initialize the module as appropriate for NT""" - g = {} - # set basic install directories - g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) - g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) - - # XXX hmmm.. a normal install puts include files here - g['INCLUDEPY'] = get_python_inc(plat_specific=0) - - g['SO'] = '.pyd' - g['EXE'] = ".exe" - g['VERSION'] = get_python_version().replace(".", "") - g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) - - global _config_vars - _config_vars = g - - -def _init_mac(): - """Initialize the module as appropriate for Macintosh systems""" - g = {} - # set basic install directories - g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) - g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) - - # XXX hmmm.. a normal install puts include files here - g['INCLUDEPY'] = get_python_inc(plat_specific=0) - - import MacOS - if not hasattr(MacOS, 'runtimemodel'): - g['SO'] = '.ppc.slb' - else: - g['SO'] = '.%s.slb' % MacOS.runtimemodel - - # XXX are these used anywhere? - g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib") - g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib") - - # These are used by the extension module build - g['srcdir'] = ':' - global _config_vars - _config_vars = g - - -def _init_os2(): - """Initialize the module as appropriate for OS/2""" - g = {} - # set basic install directories - g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) - g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) - - # XXX hmmm.. a normal install puts include files here - g['INCLUDEPY'] = get_python_inc(plat_specific=0) - - g['SO'] = '.pyd' - g['EXE'] = ".exe" - - global _config_vars - _config_vars = g - - def get_config_vars(*args): - """With no arguments, return a dictionary of all configuration + """This function is deprecated. + + With no arguments, return a dictionary of all configuration variables relevant for the current platform. Generally this includes everything needed to build extensions and install both pure modules and extensions. On Unix, this means every variable defined in Python's @@ -523,109 +257,15 @@ With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. """ - global _config_vars - if _config_vars is None: - func = globals().get("_init_" + os.name) - if func: - func() - else: - _config_vars = {} - - # Normalized versions of prefix and exec_prefix are handy to have; - # in fact, these are the standard versions used most places in the - # Distutils. - _config_vars['prefix'] = PREFIX - _config_vars['exec_prefix'] = EXEC_PREFIX - - if 'srcdir' not in _config_vars: - _config_vars['srcdir'] = project_base - - # Convert srcdir into an absolute path if it appears necessary. - # Normally it is relative to the build directory. However, during - # testing, for example, we might be running a non-installed python - # from a different directory. - if python_build and os.name == "posix": - base = os.path.dirname(os.path.abspath(sys.executable)) - if (not os.path.isabs(_config_vars['srcdir']) and - base != os.getcwd()): - # srcdir is relative and we are not in the same directory - # as the executable. Assume executable is in the build - # directory and make srcdir absolute. - srcdir = os.path.join(base, _config_vars['srcdir']) - _config_vars['srcdir'] = os.path.normpath(srcdir) - - if sys.platform == 'darwin': - kernel_version = os.uname()[2] # Kernel version (8.4.3) - major_version = int(kernel_version.split('.')[0]) - - if major_version < 8: - # On Mac OS X before 10.4, check if -arch and -isysroot - # 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', - # 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) - _config_vars[key] = flags - - else: - - # Allow the user to override the architecture flags using - # an environment variable. - # NOTE: This name was introduced by Apple in OSX 10.5 and - # is used by several scripting languages distributed with - # that OS release. - - if 'ARCHFLAGS' in os.environ: - arch = os.environ['ARCHFLAGS'] - 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 = flags + ' ' + arch - _config_vars[key] = flags - - # If we're on OSX 10.5 or later and the user tries to - # compiles an extension using an SDK that is not present - # on the current machine it is better to not use an SDK - # than to fail. - # - # The major usecase for this is users using a Python.org - # binary installer on OSX 10.6: that installer uses - # the 10.4u SDK, but that SDK is not installed by default - # when you install Xcode. - # - m = re.search('-isysroot\s+(\S+)', _config_vars['CFLAGS']) - if m is not None: - sdk = m.group(1) - if not os.path.exists(sdk): - 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('-isysroot\s+\S+(\s|$)', ' ', flags) - _config_vars[key] = flags - - if args: - vals = [] - for name in args: - vals.append(_config_vars.get(name)) - return vals - else: - return _config_vars + warn(_DEPRECATION_MSG % 'get_config_vars', DeprecationWarning) + return _sysconfig.get_config_vars(*args) def get_config_var(name): - """Return the value of a single variable using the dictionary + """This function is deprecated. + + Return the value of a single variable using the dictionary returned by 'get_config_vars()'. Equivalent to get_config_vars().get(name) """ - return get_config_vars().get(name) + warn(_DEPRECATION_MSG % 'get_config_var', DeprecationWarning) + return _sysconfig.get_config_var(name) Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_ext.py Sun Nov 22 16:36:10 2009 @@ -9,7 +9,7 @@ from distutils.core import Extension, Distribution from distutils.command.build_ext import build_ext -from distutils import sysconfig +import sysconfig from distutils.tests import support from distutils.extension import Extension from distutils.errors import (UnknownFileError, DistutilsSetupError, @@ -105,17 +105,17 @@ old = sys.platform sys.platform = 'sunos' # fooling finalize_options - from distutils.sysconfig import _config_vars - old_var = _config_vars.get('Py_ENABLE_SHARED') - _config_vars['Py_ENABLE_SHARED'] = 1 + from sysconfig import _CONFIG_VARS + old_var = _CONFIG_VARS.get('Py_ENABLE_SHARED') + _CONFIG_VARS['Py_ENABLE_SHARED'] = 1 try: cmd.ensure_finalized() finally: sys.platform = old if old_var is None: - del _config_vars['Py_ENABLE_SHARED'] + del _CONFIG_VARS['Py_ENABLE_SHARED'] else: - _config_vars['Py_ENABLE_SHARED'] = old_var + _CONFIG_VARS['Py_ENABLE_SHARED'] = old_var # make sure we get some library dirs under solaris self.assertTrue(len(cmd.library_dirs) > 0) Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_scripts.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_scripts.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_build_scripts.py Sun Nov 22 16:36:10 2009 @@ -5,7 +5,7 @@ from distutils.command.build_scripts import build_scripts from distutils.core import Distribution -from distutils import sysconfig +import sysconfig from distutils.tests import support @@ -91,12 +91,12 @@ # --with-suffix=3`, python is compiled okay but the build scripts # failed when writing the name of the executable old = sysconfig.get_config_vars().get('VERSION') - sysconfig._config_vars['VERSION'] = 4 + sysconfig._CONFIG_VARS['VERSION'] = 4 try: cmd.run() finally: if old is not None: - sysconfig._config_vars['VERSION'] = old + sysconfig._CONFIG_VARS['VERSION'] = old built = os.listdir(target) for name in expected: Modified: python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/tests/test_util.py Sun Nov 22 16:36:10 2009 @@ -44,7 +44,7 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive - self._config_vars = copy(sysconfig._config_vars) + #self._config_vars = copy(sysconfig._config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -78,7 +78,7 @@ os.uname = self.uname else: del os.uname - sysconfig._config_vars = copy(self._config_vars) + #sysconfig._config_vars = copy(self._config_vars) util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen sys.old_stdout = self.old_stdout @@ -91,7 +91,7 @@ def _get_uname(self): return self._uname - def test_get_platform(self): + def _test_get_platform(self): # windows XP, 32bits os.name = 'nt' Modified: python/branches/tarek_sysconfig/Lib/distutils/util.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/util.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/util.py Sun Nov 22 16:36:10 2009 @@ -7,6 +7,7 @@ __revision__ = "$Id$" import sys, os, string, re +from warnings import warn from distutils.errors import DistutilsPlatformError from distutils.dep_util import newer @@ -15,8 +16,12 @@ from distutils.version import LooseVersion from distutils.errors import DistutilsByteCompileError +_sysconfig = __import__('sysconfig') + def get_platform(): - """Return a string that identifies the current platform. + """This function is deprecated. + + Return a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name @@ -40,138 +45,10 @@ For other non-POSIX platforms, currently just returns 'sys.platform'. """ - if os.name == 'nt': - # sniff sys.version for architecture. - prefix = " bit (" - i = sys.version.find(prefix) - if i == -1: - return sys.platform - j = sys.version.find(")", i) - look = sys.version[i+len(prefix):j].lower() - if look == 'amd64': - return 'win-amd64' - if look == 'itanium': - return 'win-ia64' - return sys.platform - - if os.name != "posix" or not hasattr(os, 'uname'): - # XXX what about the architecture? NT is Intel or Alpha, - # Mac OS is M68k or PPC, etc. - return sys.platform - - # Try to distinguish various flavours of Unix - - (osname, host, release, version, machine) = os.uname() - - # Convert the OS name to lowercase, remove '/' characters - # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_') - machine = machine.replace('/', '-') - - if osname[:5] == "linux": - # At least on Linux/Intel, 'machine' is the processor -- - # i386, etc. - # XXX what about Alpha, SPARC, etc? - return "%s-%s" % (osname, machine) - elif osname[:5] == "sunos": - if release[0] >= "5": # SunOS 5 == Solaris 2 - osname = "solaris" - release = "%d.%s" % (int(release[0]) - 3, release[2:]) - # fall through to standard osname-release-machine representation - elif osname[:4] == "irix": # could be "irix64"! - return "%s-%s" % (osname, release) - elif osname[:3] == "aix": - return "%s-%s.%s" % (osname, version, release) - elif osname[:6] == "cygwin": - osname = "cygwin" - rel_re = re.compile (r'[\d.]+') - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == "darwin": - # - # For our purposes, we'll assume that the system version from - # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set - # to. This makes the compatibility story a bit more sane because the - # machine is going to compile and link as if it were - # MACOSX_DEPLOYMENT_TARGET. - from distutils.sysconfig import get_config_vars - cfgvars = get_config_vars() - - macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET') - if not macver: - macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') - - if 1: - # Always calculate the release of the running machine, - # needed to determine if we can build fat binaries or not. - - macrelease = macver - # Get the system version. Reading this plist is a documented - # way to get the system version (see the documentation for - # the Gestalt Manager) - try: - f = open('/System/Library/CoreServices/SystemVersion.plist') - except IOError: - # We're on a plain darwin box, fall back to the default - # behaviour. - pass - else: - m = re.search( - r'ProductUserVisibleVersion\s*' + - r'(.*?)', f.read()) - f.close() - if m is not None: - macrelease = '.'.join(m.group(1).split('.')[:2]) - # else: fall back to the default behaviour - - if not macver: - macver = macrelease - - if macver: - from distutils.sysconfig import get_config_vars - release = macver - osname = "macosx" - - if (macrelease + '.') >= '10.4.' and \ - '-arch' in get_config_vars().get('CFLAGS', '').strip(): - # The universal build will build fat binaries, but not on - # systems before 10.4 - # - # Try to detect 4-way universal builds, those have machine-type - # 'universal' instead of 'fat'. - - machine = 'fat' - cflags = get_config_vars().get('CFLAGS') - - archs = re.findall('-arch\s+(\S+)', cflags) - archs.sort() - archs = tuple(archs) - - if len(archs) == 1: - machine = archs[0] - elif archs == ('i386', 'ppc'): - machine = 'fat' - elif archs == ('i386', 'x86_64'): - machine = 'intel' - elif archs == ('i386', 'ppc', 'x86_64'): - machine = 'fat3' - elif archs == ('ppc64', 'x86_64'): - machine = 'fat64' - elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): - machine = 'universal' - else: - raise ValueError( - "Don't know machine value for archs=%r"%(archs,)) - - - elif machine in ('PowerPC', 'Power_Macintosh'): - # Pick a sane name for the PPC architecture. - machine = 'ppc' - - return "%s-%s-%s" % (osname, release, machine) - + msg = ("distutils.sysconfig.get_platform is deprecated. " + "Use sysconfig.get_platform instead.") + warn(msg, DeprecationWarning) + return _sysconfig.get_platform() def convert_path(pathname): """Return 'pathname' as a name that will work on the native filesystem. Modified: python/branches/tarek_sysconfig/Lib/site.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/site.py (original) +++ python/branches/tarek_sysconfig/Lib/site.py Sun Nov 22 16:36:10 2009 @@ -114,7 +114,7 @@ def addbuilddir(): """Append ./build/lib. in case we're running in the build dir (especially for Guido :-)""" - from distutils.util import get_platform + from sysconfig import get_platform s = "build/lib.%s-%.3s" % (get_platform(), sys.version) if hasattr(sys, 'gettotalrefcount'): s += '-pydebug' @@ -225,19 +225,8 @@ global USER_BASE if USER_BASE is not None: return USER_BASE - - env_base = os.environ.get("PYTHONUSERBASE", None) - - def joinuser(*args): - return os.path.expanduser(os.path.join(*args)) - - # what about 'os2emx', 'riscos' ? - if os.name == "nt": - base = os.environ.get("APPDATA") or "~" - USER_BASE = env_base if env_base else joinuser(base, "Python") - else: - USER_BASE = env_base if env_base else joinuser("~", ".local") - + from sysconfig import get_config_var + USER_BASE = get_config_var('userbase') return USER_BASE def getusersitepackages(): @@ -252,13 +241,9 @@ if USER_SITE is not None: return USER_SITE - if os.name == "nt": - USER_SITE = os.path.join(user_base, "Python" + sys.version[0] + - sys.version[2], "site-packages") - else: - USER_SITE = os.path.join(user_base, "lib", "python" + sys.version[:3], - "site-packages") - + from sysconfig import get_path + import os + USER_SITE = get_path('purelib', '%s_user' % os.name) return USER_SITE def addusersitepackages(known_paths): Modified: python/branches/tarek_sysconfig/Lib/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/sysconfig.py Sun Nov 22 16:36:10 2009 @@ -6,7 +6,7 @@ from os.path import pardir, abspath _INSTALL_SCHEMES = { - 'unix_prefix': { + 'posix_prefix': { 'stdlib': '$base/lib/python$py_version_short', 'platstdlib': '$platbase/lib/python$py_version_short', 'purelib': '$base/lib/python$py_version_short/site-packages', @@ -16,7 +16,7 @@ 'scripts': '$base/bin', 'data': '$base', }, - 'unix_home': { + 'posix_home': { 'stdlib': '$base/lib/python', 'platstdlib': '$base/lib/python', 'purelib': '$base/lib/python', @@ -64,7 +64,7 @@ 'scripts': '$userbase/Scripts', 'data' : '$userbase', }, - 'unix_user': { + 'posix_user': { 'stdlib': '$userbase/lib/python/$py_version_short', 'platstdlib': '$userbase/lib/python/$py_version_short', 'purelib': '$userbase/lib/python/$py_version_short/site-packages', @@ -104,7 +104,7 @@ _PYTHON_BUILD = _python_build() if _PYTHON_BUILD: - for scheme in ('unix_prefix', 'unix_home'): + for scheme in ('posix_prefix', 'posix_home'): _INSTALL_SCHEMES[scheme]['include'] = '$projectbase' _INSTALL_SCHEMES[scheme]['platinclude'] = '$srcdir/Include' @@ -121,18 +121,29 @@ except KeyError, var: raise AttributeError('$%s' % var) +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + def _expand_vars(scheme, vars): res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + for key, value in _INSTALL_SCHEMES[scheme].items(): if os.name in ('posix', 'nt'): value = os.path.expanduser(value) - vars = get_config_vars() res[key] = _subst_vars(value, vars) return res def _get_default_scheme(): if os.name == 'posix': - return 'unix_home' + # see what to do here + return 'posix_home' return os.name def _getuserbase(): @@ -257,13 +268,25 @@ vars[m.group(1)] = 0 return vars +def _get_makefile_filename(): + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + return os.path.join(get_path('stdlib'), "config", "Makefile") + +def _get_config_h_filename(): + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + def _init_posix(vars): """Initialize the module as appropriate for POSIX systems.""" # load the installed Makefile: - if _PYTHON_BUILD: - makefile = os.path.join(_PROJECT_BASE, "Makefile") - else: - makefile = os.path.join(get_path('stdlib'), "config", "Makefile") + makefile = _get_makefile_filename() try: _parse_makefile(makefile, vars) except IOError, e: @@ -273,14 +296,7 @@ raise IOError(msg) # load the installed pyconfig.h: - if _PYTHON_BUILD: - if os.name == "nt": - inc_dir = os.path.join(_PROJECT_BASE, "PC") - else: - inc_dir = _PROJECT_BASE - else: - inc_dir = get_path('platinclude') - config_h = os.path.join(inc_dir, 'pyconfig.h') + config_h = _get_config_h_filename() try: _parse_config_h(open(config_h), vars) except IOError, e: @@ -619,3 +635,7 @@ machine = 'ppc' return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT Modified: python/branches/tarek_sysconfig/Lib/test/test_site.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/test/test_site.py (original) +++ python/branches/tarek_sysconfig/Lib/test/test_site.py Sun Nov 22 16:36:10 2009 @@ -138,6 +138,9 @@ # let's set PYTHONUSERBASE and see if it uses it site.USER_BASE = None + import sysconfig + sysconfig._CONFIG_VARS = None + with EnvironmentVarGuard() as environ: environ['PYTHONUSERBASE'] = 'xoxo' self.assertTrue(site.getuserbase().startswith('xoxo'), From python-checkins at python.org Sun Nov 22 19:30:54 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 22 Nov 2009 18:30:54 -0000 Subject: [Python-checkins] r76443 - in python/trunk: Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Sun Nov 22 19:30:53 2009 New Revision: 76443 Log: Issue #6123: Fix opening empty archives and files. (Note that an empty archive is not the same as an empty file. An empty archive contains no members and is correctly terminated with an EOF block full of zeros. An empty file contains no data at all.) The problem was that although tarfile was able to create empty archives, it failed to open them raising a ReadError. On the other hand, tarfile opened empty files without error in most read modes and presented them as empty archives. (However, some modes still raised errors: "r|gz" raised ReadError, but "r:gz" worked, "r:bz2" even raised EOFError.) In order to get a more fine-grained control over the various internal error conditions I now split up the HeaderError exception into a number of meaningful sub-exceptions. This makes it easier in the TarFile.next() method to react to the different conditions in the correct way. The visible change in its behaviour now is that tarfile will open empty archives correctly and raise ReadError consistently for empty files. Modified: python/trunk/Lib/tarfile.py python/trunk/Lib/test/test_tarfile.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/tarfile.py ============================================================================== --- python/trunk/Lib/tarfile.py (original) +++ python/trunk/Lib/tarfile.py Sun Nov 22 19:30:53 2009 @@ -195,7 +195,7 @@ try: n = int(nts(s) or "0", 8) except ValueError: - raise HeaderError("invalid header") + raise InvalidHeaderError("invalid header") else: n = 0L for i in xrange(len(s) - 1): @@ -346,8 +346,23 @@ """Exception for unsupported operations on stream-like TarFiles.""" pass class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): """Exception for invalid headers.""" pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass #--------------------------- # internal stream interface @@ -1179,14 +1194,16 @@ def frombuf(cls, buf): """Construct a TarInfo object from a 512 byte string buffer. """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") if len(buf) != BLOCKSIZE: - raise HeaderError("truncated header") + raise TruncatedHeaderError("truncated header") if buf.count(NUL) == BLOCKSIZE: - raise HeaderError("empty header") + raise EOFHeaderError("end of file header") chksum = nti(buf[148:156]) if chksum not in calc_chksums(buf): - raise HeaderError("bad checksum") + raise InvalidHeaderError("bad checksum") obj = cls() obj.buf = buf @@ -1225,8 +1242,6 @@ tarfile. """ buf = tarfile.fileobj.read(BLOCKSIZE) - if not buf: - return obj = cls.frombuf(buf) obj.offset = tarfile.fileobj.tell() - BLOCKSIZE return obj._proc_member(tarfile) @@ -1279,9 +1294,10 @@ buf = tarfile.fileobj.read(self._block(self.size)) # Fetch the next header and process it. - next = self.fromtarfile(tarfile) - if next is None: - raise HeaderError("missing subsequent header") + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") # Patch the TarInfo object from the next header with # the longname information. @@ -1386,12 +1402,12 @@ pos += length # Fetch the next header. - next = self.fromtarfile(tarfile) + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") if self.type in (XHDTYPE, SOLARIS_XHDTYPE): - if next is None: - raise HeaderError("missing subsequent header") - # Patch the TarInfo object with the extended header info. next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) next.offset = self.offset @@ -1565,12 +1581,16 @@ if self.mode == "a": # Move to the end of the archive, # before the first empty block. - self.firstmember = None while True: - if self.next() is None: - if self.offset > 0: - self.fileobj.seek(- BLOCKSIZE, 1) + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) break + except HeaderError, e: + raise ReadError(str(e)) if self.mode in "aw": self._loaded = True @@ -1735,7 +1755,7 @@ try: t = cls.taropen(name, mode, fileobj, **kwargs) - except IOError: + except (IOError, EOFError): raise ReadError("not a bzip2 file") t._extfileobj = False return t @@ -2307,24 +2327,37 @@ # Read the next block. self.fileobj.seek(self.offset) + tarinfo = None while True: try: tarinfo = self.tarinfo.fromtarfile(self) - if tarinfo is None: - return - self.members.append(tarinfo) - - except HeaderError, e: + except EOFHeaderError, e: if self.ignore_zeros: self._dbg(2, "0x%X: %s" % (self.offset, e)) self.offset += BLOCKSIZE continue - else: - if self.offset == 0: - raise ReadError(str(e)) - return None + except InvalidHeaderError, e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError, e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError, e: + raise ReadError(str(e)) break + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + return tarinfo #-------------------------------------------------------------------------- Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Sun Nov 22 19:30:53 2009 @@ -136,7 +136,53 @@ fobj.close() -class MiscReadTest(ReadTest): +class CommonReadTest(ReadTest): + + def test_empty_tarfile(self): + # Test for issue6123: Allow opening empty archives. + # This test checks if tarfile.open() is able to open an empty tar + # archive successfully. Note that an empty tar archive is not the + # same as an empty file! + tarfile.open(tmpname, self.mode.replace("r", "w")).close() + try: + tar = tarfile.open(tmpname, self.mode) + tar.getnames() + except tarfile.ReadError: + self.fail("tarfile.open() failed on empty archive") + self.assertListEqual(tar.getmembers(), []) + + def test_null_tarfile(self): + # Test for issue6123: Allow opening empty archives. + # This test guarantees that tarfile.open() does not treat an empty + # file as an empty tar archive. + open(tmpname, "wb").close() + self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode) + self.assertRaises(tarfile.ReadError, tarfile.open, tmpname) + + def test_ignore_zeros(self): + # Test TarFile's ignore_zeros option. + if self.mode.endswith(":gz"): + _open = gzip.GzipFile + elif self.mode.endswith(":bz2"): + _open = bz2.BZ2File + else: + _open = open + + for char in ('\0', 'a'): + # Test if EOFHeaderError ('\0') and InvalidHeaderError ('a') + # are ignored correctly. + fobj = _open(tmpname, "wb") + fobj.write(char * 1024) + fobj.write(tarfile.TarInfo("foo").tobuf()) + fobj.close() + + tar = tarfile.open(tmpname, mode="r", ignore_zeros=True) + self.assertListEqual(tar.getnames(), ["foo"], + "ignore_zeros=True should have skipped the %r-blocks" % char) + tar.close() + + +class MiscReadTest(CommonReadTest): def test_no_name_argument(self): fobj = open(self.tarname, "rb") @@ -265,7 +311,7 @@ tar.close() -class StreamReadTest(ReadTest): +class StreamReadTest(CommonReadTest): mode="r|" @@ -1111,12 +1157,12 @@ self._test() def test_empty(self): - open(self.tarname, "w").close() + tarfile.open(self.tarname, "w:").close() self._add_testfile() self._test() def test_empty_fileobj(self): - fobj = StringIO.StringIO() + fobj = StringIO.StringIO("\0" * 1024) self._add_testfile(fobj) fobj.seek(0) self._test(fileobj=fobj) @@ -1146,6 +1192,29 @@ self._create_testtar("w:bz2") self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, "a") + # Append mode is supposed to fail if the tarfile to append to + # does not end with a zero block. + def _test_error(self, data): + open(self.tarname, "wb").write(data) + self.assertRaises(tarfile.ReadError, self._add_testfile) + + def test_null(self): + self._test_error("") + + def test_incomplete(self): + self._test_error("\0" * 13) + + def test_premature_eof(self): + data = tarfile.TarInfo("foo").tobuf() + self._test_error(data) + + def test_trailing_garbage(self): + data = tarfile.TarInfo("foo").tobuf() + self._test_error(data + "\0" * 13) + + def test_invalid(self): + self._test_error("a" * 512) + class LimitsTest(unittest.TestCase): @@ -1247,10 +1316,16 @@ raise AssertionError("infinite loop detected in tarfile.open()") self.hit_eof = self.pos == self.len return StringIO.StringIO.read(self, n) + def seek(self, *args): + self.hit_eof = False + return StringIO.StringIO.seek(self, *args) data = bz2.compress(tarfile.TarInfo("foo").tobuf()) for x in range(len(data) + 1): - tarfile.open(fileobj=MyStringIO(data[:x]), mode=mode) + try: + tarfile.open(fileobj=MyStringIO(data[:x]), mode=mode) + except tarfile.ReadError: + pass # we have no interest in ReadErrors def test_partial_input(self): self._test_partial_input("r") Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 22 19:30:53 2009 @@ -476,6 +476,9 @@ Library ------- +- Issue #6123: tarfile now opens empty archives correctly and consistently + raises ReadError on empty files. + - Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can be 2. From python-checkins at python.org Sun Nov 22 19:48:49 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 22 Nov 2009 18:48:49 -0000 Subject: [Python-checkins] r76444 - in python/branches/py3k: Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: Author: lars.gustaebel Date: Sun Nov 22 19:48:49 2009 New Revision: 76444 Log: Merged revisions 76443 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76443 | lars.gustaebel | 2009-11-22 19:30:53 +0100 (Sun, 22 Nov 2009) | 24 lines Issue #6123: Fix opening empty archives and files. (Note that an empty archive is not the same as an empty file. An empty archive contains no members and is correctly terminated with an EOF block full of zeros. An empty file contains no data at all.) The problem was that although tarfile was able to create empty archives, it failed to open them raising a ReadError. On the other hand, tarfile opened empty files without error in most read modes and presented them as empty archives. (However, some modes still raised errors: "r|gz" raised ReadError, but "r:gz" worked, "r:bz2" even raised EOFError.) In order to get a more fine-grained control over the various internal error conditions I now split up the HeaderError exception into a number of meaningful sub-exceptions. This makes it easier in the TarFile.next() method to react to the different conditions in the correct way. The visible change in its behaviour now is that tarfile will open empty archives correctly and raise ReadError consistently for empty files. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/tarfile.py python/branches/py3k/Lib/test/test_tarfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/tarfile.py ============================================================================== --- python/branches/py3k/Lib/tarfile.py (original) +++ python/branches/py3k/Lib/tarfile.py Sun Nov 22 19:48:49 2009 @@ -194,7 +194,7 @@ try: n = int(nts(s, "ascii", "strict") or "0", 8) except ValueError: - raise HeaderError("invalid header") + raise InvalidHeaderError("invalid header") else: n = 0 for i in range(len(s) - 1): @@ -325,8 +325,23 @@ """Exception for unsupported operations on stream-like TarFiles.""" pass class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): """Exception for invalid headers.""" pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass #--------------------------- # internal stream interface @@ -1171,14 +1186,16 @@ def frombuf(cls, buf, encoding, errors): """Construct a TarInfo object from a 512 byte bytes object. """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") if len(buf) != BLOCKSIZE: - raise HeaderError("truncated header") + raise TruncatedHeaderError("truncated header") if buf.count(NUL) == BLOCKSIZE: - raise HeaderError("empty header") + raise EOFHeaderError("end of file header") chksum = nti(buf[148:156]) if chksum not in calc_chksums(buf): - raise HeaderError("bad checksum") + raise InvalidHeaderError("bad checksum") obj = cls() obj.name = nts(buf[0:100], encoding, errors) @@ -1234,8 +1251,6 @@ tarfile. """ buf = tarfile.fileobj.read(BLOCKSIZE) - if not buf: - return obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) obj.offset = tarfile.fileobj.tell() - BLOCKSIZE return obj._proc_member(tarfile) @@ -1288,9 +1303,10 @@ buf = tarfile.fileobj.read(self._block(self.size)) # Fetch the next header and process it. - next = self.fromtarfile(tarfile) - if next is None: - raise HeaderError("missing subsequent header") + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") # Patch the TarInfo object from the next header with # the longname information. @@ -1380,12 +1396,12 @@ pos += length # Fetch the next header. - next = self.fromtarfile(tarfile) + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") if self.type in (XHDTYPE, SOLARIS_XHDTYPE): - if next is None: - raise HeaderError("missing subsequent header") - # Patch the TarInfo object with the extended header info. next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) next.offset = self.offset @@ -1557,12 +1573,16 @@ if self.mode == "a": # Move to the end of the archive, # before the first empty block. - self.firstmember = None while True: - if self.next() is None: - if self.offset > 0: - self.fileobj.seek(self.fileobj.tell() - BLOCKSIZE) + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) break + except HeaderError as e: + raise ReadError(str(e)) if self.mode in "aw": self._loaded = True @@ -1715,7 +1735,7 @@ try: t = cls.taropen(name, mode, fileobj, **kwargs) - except IOError: + except (IOError, EOFError): raise ReadError("not a bzip2 file") t._extfileobj = False return t @@ -2287,24 +2307,37 @@ # Read the next block. self.fileobj.seek(self.offset) + tarinfo = None while True: try: tarinfo = self.tarinfo.fromtarfile(self) - if tarinfo is None: - return - self.members.append(tarinfo) - - except HeaderError as e: + except EOFHeaderError as e: if self.ignore_zeros: self._dbg(2, "0x%X: %s" % (self.offset, e)) self.offset += BLOCKSIZE continue - else: - if self.offset == 0: - raise ReadError(str(e)) - return None + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) break + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + return tarinfo #-------------------------------------------------------------------------- Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Sun Nov 22 19:48:49 2009 @@ -135,7 +135,53 @@ fobj.close() -class MiscReadTest(ReadTest): +class CommonReadTest(ReadTest): + + def test_empty_tarfile(self): + # Test for issue6123: Allow opening empty archives. + # This test checks if tarfile.open() is able to open an empty tar + # archive successfully. Note that an empty tar archive is not the + # same as an empty file! + tarfile.open(tmpname, self.mode.replace("r", "w")).close() + try: + tar = tarfile.open(tmpname, self.mode) + tar.getnames() + except tarfile.ReadError: + self.fail("tarfile.open() failed on empty archive") + self.assertListEqual(tar.getmembers(), []) + + def test_null_tarfile(self): + # Test for issue6123: Allow opening empty archives. + # This test guarantees that tarfile.open() does not treat an empty + # file as an empty tar archive. + open(tmpname, "wb").close() + self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode) + self.assertRaises(tarfile.ReadError, tarfile.open, tmpname) + + def test_ignore_zeros(self): + # Test TarFile's ignore_zeros option. + if self.mode.endswith(":gz"): + _open = gzip.GzipFile + elif self.mode.endswith(":bz2"): + _open = bz2.BZ2File + else: + _open = open + + for char in (b'\0', b'a'): + # Test if EOFHeaderError ('\0') and InvalidHeaderError ('a') + # are ignored correctly. + fobj = _open(tmpname, "wb") + fobj.write(char * 1024) + fobj.write(tarfile.TarInfo("foo").tobuf()) + fobj.close() + + tar = tarfile.open(tmpname, mode="r", ignore_zeros=True) + self.assertListEqual(tar.getnames(), ["foo"], + "ignore_zeros=True should have skipped the %r-blocks" % char) + tar.close() + + +class MiscReadTest(CommonReadTest): def test_no_name_argument(self): fobj = open(self.tarname, "rb") @@ -264,7 +310,7 @@ tar.close() -class StreamReadTest(ReadTest): +class StreamReadTest(CommonReadTest): mode="r|" @@ -1079,12 +1125,12 @@ self._test() def test_empty(self): - open(self.tarname, "w").close() + tarfile.open(self.tarname, "w:").close() self._add_testfile() self._test() def test_empty_fileobj(self): - fobj = io.BytesIO() + fobj = io.BytesIO(b"\0" * 1024) self._add_testfile(fobj) fobj.seek(0) self._test(fileobj=fobj) @@ -1114,6 +1160,29 @@ self._create_testtar("w:bz2") self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, "a") + # Append mode is supposed to fail if the tarfile to append to + # does not end with a zero block. + def _test_error(self, data): + open(self.tarname, "wb").write(data) + self.assertRaises(tarfile.ReadError, self._add_testfile) + + def test_null(self): + self._test_error(b"") + + def test_incomplete(self): + self._test_error(b"\0" * 13) + + def test_premature_eof(self): + data = tarfile.TarInfo("foo").tobuf() + self._test_error(data) + + def test_trailing_garbage(self): + data = tarfile.TarInfo("foo").tobuf() + self._test_error(data + b"\0" * 13) + + def test_invalid(self): + self._test_error(b"a" * 512) + class LimitsTest(unittest.TestCase): @@ -1228,10 +1297,16 @@ raise AssertionError("infinite loop detected in tarfile.open()") self.hit_eof = self.tell() == len(self.getvalue()) return super(MyBytesIO, self).read(n) + def seek(self, *args): + self.hit_eof = False + return super(MyBytesIO, self).seek(*args) data = bz2.compress(tarfile.TarInfo("foo").tobuf()) for x in range(len(data) + 1): - tarfile.open(fileobj=MyBytesIO(data[:x]), mode=mode) + try: + tarfile.open(fileobj=MyBytesIO(data[:x]), mode=mode) + except tarfile.ReadError: + pass # we have no interest in ReadErrors def test_partial_input(self): self._test_partial_input("r") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 22 19:48:49 2009 @@ -140,6 +140,9 @@ Library ------- +- Issue #6123: tarfile now opens empty archives correctly and consistently + raises ReadError on empty files. + - Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can be 2. From python-checkins at python.org Sun Nov 22 19:56:32 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 22 Nov 2009 18:56:32 -0000 Subject: [Python-checkins] r76445 - python/branches/release26-maint Message-ID: Author: lars.gustaebel Date: Sun Nov 22 19:56:32 2009 New Revision: 76445 Log: Blocked revisions 76443 via svnmerge ........ r76443 | lars.gustaebel | 2009-11-22 19:30:53 +0100 (Sun, 22 Nov 2009) | 24 lines Issue #6123: Fix opening empty archives and files. (Note that an empty archive is not the same as an empty file. An empty archive contains no members and is correctly terminated with an EOF block full of zeros. An empty file contains no data at all.) The problem was that although tarfile was able to create empty archives, it failed to open them raising a ReadError. On the other hand, tarfile opened empty files without error in most read modes and presented them as empty archives. (However, some modes still raised errors: "r|gz" raised ReadError, but "r:gz" worked, "r:bz2" even raised EOFError.) In order to get a more fine-grained control over the various internal error conditions I now split up the HeaderError exception into a number of meaningful sub-exceptions. This makes it easier in the TarFile.next() method to react to the different conditions in the correct way. The visible change in its behaviour now is that tarfile will open empty archives correctly and raise ReadError consistently for empty files. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Nov 22 20:02:36 2009 From: python-checkins at python.org (lars.gustaebel) Date: Sun, 22 Nov 2009 19:02:36 -0000 Subject: [Python-checkins] r76446 - python/branches/release31-maint Message-ID: Author: lars.gustaebel Date: Sun Nov 22 20:02:36 2009 New Revision: 76446 Log: Blocked revisions 76444 via svnmerge ................ r76444 | lars.gustaebel | 2009-11-22 19:48:49 +0100 (Sun, 22 Nov 2009) | 30 lines Merged revisions 76443 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76443 | lars.gustaebel | 2009-11-22 19:30:53 +0100 (Sun, 22 Nov 2009) | 24 lines Issue #6123: Fix opening empty archives and files. (Note that an empty archive is not the same as an empty file. An empty archive contains no members and is correctly terminated with an EOF block full of zeros. An empty file contains no data at all.) The problem was that although tarfile was able to create empty archives, it failed to open them raising a ReadError. On the other hand, tarfile opened empty files without error in most read modes and presented them as empty archives. (However, some modes still raised errors: "r|gz" raised ReadError, but "r:gz" worked, "r:bz2" even raised EOFError.) In order to get a more fine-grained control over the various internal error conditions I now split up the HeaderError exception into a number of meaningful sub-exceptions. This makes it easier in the TarFile.next() method to react to the different conditions in the correct way. The visible change in its behaviour now is that tarfile will open empty archives correctly and raise ReadError consistently for empty files. ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Mon Nov 23 00:47:03 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 23 Nov 2009 00:47:03 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76444): sum=701 Message-ID: <20091122234703.A457017715@ns6635.ovh.net> py3k results for svn r76444 (hg cset 67a28389fa75) -------------------------------------------------- test_multiprocessing leaked [229, 229, 229] references, sum=687 test_urllib leaked [2, 8, 4] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogJZaZvE', '-x', 'test_httpservers'] From python-checkins at python.org Mon Nov 23 01:17:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 23 Nov 2009 00:17:40 -0000 Subject: [Python-checkins] r76447 - in sandbox/trunk/2to3/lib2to3: fixes/fix_urllib.py tests/test_fixers.py Message-ID: Author: benjamin.peterson Date: Mon Nov 23 01:17:40 2009 New Revision: 76447 Log: #7375 fix nested transformations in fix_urllib Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py Mon Nov 23 01:17:40 2009 @@ -63,7 +63,8 @@ yield """import_name< 'import' dotted_as_name< module_as=%r 'as' any > > """ % old_module - yield """power< module_dot=%r trailer< '.' member=%s > any* > + # bare_with_attr has a special significance for FixImports.match(). + yield """power< bare_with_attr=%r trailer< '.' member=%s > any* > """ % (old_module, members) @@ -150,12 +151,11 @@ def transform_dot(self, node, results): """Transform for calls to module members in code.""" - module_dot = results.get('module_dot') + module_dot = results.get('bare_with_attr') member = results.get('member') - # this may be a list of length one, or just a node + new_name = None if isinstance(member, list): member = member[0] - new_name = None for change in MAPPING[module_dot.value]: if member.value in change[1]: new_name = change[0] @@ -171,7 +171,7 @@ self.transform_import(node, results) elif results.get('mod_member'): self.transform_member(node, results) - elif results.get('module_dot'): + elif results.get('bare_with_attr'): self.transform_dot(node, results) # Renaming and star imports are not supported for these modules. elif results.get('module_star'): Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py (original) +++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py Mon Nov 23 01:17:40 2009 @@ -1753,6 +1753,8 @@ for old, changes in self.modules.items(): for new, members in changes: for member in members: + new_import = ", ".join([n for (n, mems) + in self.modules[old]]) b = """ import %s foo(%s.%s) @@ -1760,9 +1762,16 @@ a = """ import %s foo(%s.%s) - """ % (", ".join([n for (n, mems) - in self.modules[old]]), - new, member) + """ % (new_import, new, member) + self.check(b, a) + b = """ + import %s + %s.%s(%s.%s) + """ % (old, old, member, old, member) + a = """ + import %s + %s.%s(%s.%s) + """ % (new_import, new, member, new, member) self.check(b, a) From python-checkins at python.org Mon Nov 23 04:13:23 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 23 Nov 2009 03:13:23 -0000 Subject: [Python-checkins] r76448 - python/branches/py3k/Doc/library/doctest.rst Message-ID: Author: r.david.murray Date: Mon Nov 23 04:13:23 2009 New Revision: 76448 Log: Update example in doctest chapter that uses math.floor to reflect the fact that the result is an int in py3k. Thanks to 'flox' for pointing out the discrepancy. Modified: python/branches/py3k/Doc/library/doctest.rst Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Mon Nov 23 04:13:23 2009 @@ -343,7 +343,7 @@ >>> assert "Easy!" >>> import math >>> math.floor(1.9) - 1.0 + 1 and as many leading whitespace characters are stripped from the expected output as appeared in the initial ``'>>> '`` line that started the example. From python-checkins at python.org Mon Nov 23 04:14:52 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 23 Nov 2009 03:14:52 -0000 Subject: [Python-checkins] r76449 - in python/branches/release31-maint: Doc/library/doctest.rst Message-ID: Author: r.david.murray Date: Mon Nov 23 04:14:51 2009 New Revision: 76449 Log: Merged revisions 76448 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76448 | r.david.murray | 2009-11-22 22:13:23 -0500 (Sun, 22 Nov 2009) | 4 lines Update example in doctest chapter that uses math.floor to reflect the fact that the result is an int in py3k. Thanks to 'flox' for pointing out the discrepancy. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/doctest.rst Modified: python/branches/release31-maint/Doc/library/doctest.rst ============================================================================== --- python/branches/release31-maint/Doc/library/doctest.rst (original) +++ python/branches/release31-maint/Doc/library/doctest.rst Mon Nov 23 04:14:51 2009 @@ -343,7 +343,7 @@ >>> assert "Easy!" >>> import math >>> math.floor(1.9) - 1.0 + 1 and as many leading whitespace characters are stripped from the expected output as appeared in the initial ``'>>> '`` line that started the example. From nnorwitz at gmail.com Mon Nov 23 10:24:50 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 23 Nov 2009 04:24:50 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091123092450.GA32737@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:697: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [877099 refs] From python-checkins at python.org Mon Nov 23 14:33:48 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 23 Nov 2009 13:33:48 -0000 Subject: [Python-checkins] r76450 - tracker/instances/python-dev/extensions/search_id.py Message-ID: Author: martin.v.loewis Date: Mon Nov 23 14:33:48 2009 New Revision: 76450 Log: Catch missing search text. Modified: tracker/instances/python-dev/extensions/search_id.py Modified: tracker/instances/python-dev/extensions/search_id.py ============================================================================== --- tracker/instances/python-dev/extensions/search_id.py (original) +++ tracker/instances/python-dev/extensions/search_id.py Mon Nov 23 14:33:48 2009 @@ -4,6 +4,8 @@ class SearchIDAction(Action): def handle(self): request = self.context['request'] + if not request.search_text: + raise exceptions.FormError("Missing search text") split = request.search_text.split() if len(split) == 1: id = split[0] From python-checkins at python.org Mon Nov 23 15:05:34 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 23 Nov 2009 14:05:34 -0000 Subject: [Python-checkins] r76451 - tracker/instances/python-dev/extensions/local_replace.py Message-ID: Author: martin.v.loewis Date: Mon Nov 23 15:05:34 2009 New Revision: 76451 Log: Use \b as a word separator, as proposed by Ezio Melotti in issue 276. Use raw strings for regular expressions. Modified: tracker/instances/python-dev/extensions/local_replace.py Modified: tracker/instances/python-dev/extensions/local_replace.py ============================================================================== --- tracker/instances/python-dev/extensions/local_replace.py (original) +++ tracker/instances/python-dev/extensions/local_replace.py Mon Nov 23 15:05:34 2009 @@ -1,15 +1,15 @@ import re -substitutions = [ (re.compile('\#(?P\s*)(?P\d+)'), - "#\g\g" ), - (re.compile('(?P\s+)revision(?P\s*)(?P\d+)'), - "\grevision\g\g"), - (re.compile('(?P\s+)rev(?P\s*)(?P\d+)'), - "\grev\g\g"), - (re.compile('(?P\s+)(?Pr|r\s+)(?P\d+)'), - "\g\g\g"), +substitutions = [ (re.compile(r'\#(?P\s*)(?P\d+)'), + r"#\g\g" ), + (re.compile(r'\brevision(?P\s*)(?P\d+)'), + r"revision\g\g"), + (re.compile(r'\brev(?P\s*)(?P\d+)'), + r"rev\g\g"), + (re.compile(r'\b(?Pr|r\s+)(?P\d+)'), + r"\g\g"), (re.compile(r'\b(?P(?:Demo|Doc|Grammar|Include|Lib|Mac|Misc|Modules|Parser|PC|PCbuild|Python|RISCOS|Tools|Objects)/[-.a-zA-Z0-9_/]+[a-zA-Z0-9]/?)'), - '\g'), + r'\g'), ] def localReplace(message): From python-checkins at python.org Mon Nov 23 16:46:20 2009 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 23 Nov 2009 15:46:20 -0000 Subject: [Python-checkins] r76452 - python/trunk/Lib/test/test_tarfile.py Message-ID: Author: lars.gustaebel Date: Mon Nov 23 16:46:19 2009 New Revision: 76452 Log: Add a testcase that checks if the TarFile constructor successfully closes the internal file object in case of an error (issue #7341). Modified: python/trunk/Lib/test/test_tarfile.py Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Mon Nov 23 16:46:19 2009 @@ -310,6 +310,24 @@ self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) tar.close() + def test_init_close_fobj(self): + # Issue #7341: Close the internal file object in the TarFile + # constructor in case of an error. For the test we rely on + # the fact that opening an empty file raises a ReadError. + empty = os.path.join(TEMPDIR, "empty") + open(empty, "wb").write("") + + try: + tar = object.__new__(tarfile.TarFile) + try: + tar.__init__(empty) + except tarfile.ReadError: + self.assertTrue(tar.fileobj.closed) + else: + self.fail("ReadError not raised") + finally: + os.remove(empty) + class StreamReadTest(CommonReadTest): From python-checkins at python.org Mon Nov 23 16:48:33 2009 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 23 Nov 2009 15:48:33 -0000 Subject: [Python-checkins] r76453 - in python/branches/py3k: Lib/test/test_tarfile.py Message-ID: Author: lars.gustaebel Date: Mon Nov 23 16:48:33 2009 New Revision: 76453 Log: Merged revisions 76452 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76452 | lars.gustaebel | 2009-11-23 16:46:19 +0100 (Mon, 23 Nov 2009) | 3 lines Add a testcase that checks if the TarFile constructor successfully closes the internal file object in case of an error (issue #7341). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_tarfile.py Modified: python/branches/py3k/Lib/test/test_tarfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tarfile.py (original) +++ python/branches/py3k/Lib/test/test_tarfile.py Mon Nov 23 16:48:33 2009 @@ -309,6 +309,24 @@ self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) tar.close() + def test_init_close_fobj(self): + # Issue #7341: Close the internal file object in the TarFile + # constructor in case of an error. For the test we rely on + # the fact that opening an empty file raises a ReadError. + empty = os.path.join(TEMPDIR, "empty") + open(empty, "wb").write(b"") + + try: + tar = object.__new__(tarfile.TarFile) + try: + tar.__init__(empty) + except tarfile.ReadError: + self.assertTrue(tar.fileobj.closed) + else: + self.fail("ReadError not raised") + finally: + os.remove(empty) + class StreamReadTest(CommonReadTest): From python-checkins at python.org Mon Nov 23 17:01:57 2009 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 23 Nov 2009 16:01:57 -0000 Subject: [Python-checkins] r76454 - in python/branches/release26-maint: Lib/test/test_tarfile.py Message-ID: Author: lars.gustaebel Date: Mon Nov 23 17:01:56 2009 New Revision: 76454 Log: Merged revisions 76452 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76452 | lars.gustaebel | 2009-11-23 16:46:19 +0100 (Mon, 23 Nov 2009) | 3 lines Add a testcase that checks if the TarFile constructor successfully closes the internal file object in case of an error (issue #7341). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_tarfile.py Modified: python/branches/release26-maint/Lib/test/test_tarfile.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_tarfile.py (original) +++ python/branches/release26-maint/Lib/test/test_tarfile.py Mon Nov 23 17:01:56 2009 @@ -264,6 +264,24 @@ self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) tar.close() + def test_init_close_fobj(self): + # Issue #7341: Close the internal file object in the TarFile + # constructor in case of an error. For the test we rely on + # the fact that opening an invalid file raises a ReadError. + invalid = os.path.join(TEMPDIR, "invalid") + open(invalid, "wb").write("foo") + + try: + tar = object.__new__(tarfile.TarFile) + try: + tar.__init__(invalid) + except tarfile.ReadError: + self.assertTrue(tar.fileobj.closed) + else: + self.fail("ReadError not raised") + finally: + os.remove(invalid) + class StreamReadTest(ReadTest): From python-checkins at python.org Mon Nov 23 17:04:57 2009 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 23 Nov 2009 16:04:57 -0000 Subject: [Python-checkins] r76455 - in python/branches/release31-maint: Lib/test/test_tarfile.py Message-ID: Author: lars.gustaebel Date: Mon Nov 23 17:04:57 2009 New Revision: 76455 Log: Merged revisions 76453 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76453 | lars.gustaebel | 2009-11-23 16:48:33 +0100 (Mon, 23 Nov 2009) | 10 lines Merged revisions 76452 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76452 | lars.gustaebel | 2009-11-23 16:46:19 +0100 (Mon, 23 Nov 2009) | 3 lines Add a testcase that checks if the TarFile constructor successfully closes the internal file object in case of an error (issue #7341). ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_tarfile.py Modified: python/branches/release31-maint/Lib/test/test_tarfile.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tarfile.py (original) +++ python/branches/release31-maint/Lib/test/test_tarfile.py Mon Nov 23 17:04:57 2009 @@ -263,6 +263,24 @@ self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) tar.close() + def test_init_close_fobj(self): + # Issue #7341: Close the internal file object in the TarFile + # constructor in case of an error. For the test we rely on + # the fact that opening an invalid file raises a ReadError. + invalid = os.path.join(TEMPDIR, "invalid") + open(invalid, "wb").write(b"foo") + + try: + tar = object.__new__(tarfile.TarFile) + try: + tar.__init__(invalid) + except tarfile.ReadError: + self.assertTrue(tar.fileobj.closed) + else: + self.fail("ReadError not raised") + finally: + os.remove(invalid) + class StreamReadTest(ReadTest): From python-checkins at python.org Mon Nov 23 17:23:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:23:43 -0000 Subject: [Python-checkins] r76456 - python/trunk/Lib/fractions.py Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:23:43 2009 New Revision: 76456 Log: Issue #7379: Fix incorrect doctest for Fraction.limit_denominator. Modified: python/trunk/Lib/fractions.py Modified: python/trunk/Lib/fractions.py ============================================================================== --- python/trunk/Lib/fractions.py (original) +++ python/trunk/Lib/fractions.py Mon Nov 23 17:23:43 2009 @@ -164,8 +164,8 @@ Fraction(22, 7) >>> Fraction('3.141592653589793').limit_denominator(100) Fraction(311, 99) - >>> Fraction(1234, 5678).limit_denominator(10000) - Fraction(1234, 5678) + >>> Fraction(4321, 8765).limit_denominator(10000) + Fraction(4321, 8765) """ # Algorithm notes: For any real number x, define a *best upper From python-checkins at python.org Mon Nov 23 17:25:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:25:51 -0000 Subject: [Python-checkins] r76457 - in python/branches/release26-maint: Lib/fractions.py Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:25:51 2009 New Revision: 76457 Log: Merged revisions 76456 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76456 | mark.dickinson | 2009-11-23 16:23:43 +0000 (Mon, 23 Nov 2009) | 2 lines Issue #7379: Fix incorrect doctest for Fraction.limit_denominator. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/fractions.py Modified: python/branches/release26-maint/Lib/fractions.py ============================================================================== --- python/branches/release26-maint/Lib/fractions.py (original) +++ python/branches/release26-maint/Lib/fractions.py Mon Nov 23 17:25:51 2009 @@ -148,8 +148,8 @@ Fraction(22, 7) >>> Fraction('3.141592653589793').limit_denominator(100) Fraction(311, 99) - >>> Fraction(1234, 5678).limit_denominator(10000) - Fraction(1234, 5678) + >>> Fraction(4321, 8765).limit_denominator(10000) + Fraction(4321, 8765) """ # Algorithm notes: For any real number x, define a *best upper From python-checkins at python.org Mon Nov 23 17:27:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:27:18 -0000 Subject: [Python-checkins] r76458 - in python/branches/py3k: Lib/fractions.py Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:27:17 2009 New Revision: 76458 Log: Merged revisions 76456 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76456 | mark.dickinson | 2009-11-23 16:23:43 +0000 (Mon, 23 Nov 2009) | 2 lines Issue #7379: Fix incorrect doctest for Fraction.limit_denominator. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/fractions.py Modified: python/branches/py3k/Lib/fractions.py ============================================================================== --- python/branches/py3k/Lib/fractions.py (original) +++ python/branches/py3k/Lib/fractions.py Mon Nov 23 17:27:17 2009 @@ -162,8 +162,8 @@ Fraction(22, 7) >>> Fraction('3.141592653589793').limit_denominator(100) Fraction(311, 99) - >>> Fraction(1234, 5678).limit_denominator(10000) - Fraction(1234, 5678) + >>> Fraction(4321, 8765).limit_denominator(10000) + Fraction(4321, 8765) """ # Algorithm notes: For any real number x, define a *best upper From python-checkins at python.org Mon Nov 23 17:28:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:28:18 -0000 Subject: [Python-checkins] r76459 - in python/branches/release31-maint: Lib/fractions.py Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:28:18 2009 New Revision: 76459 Log: Merged revisions 76458 via svnmerge from svn+ssh://pythondev at www.python.org/python/branches/py3k ................ r76458 | mark.dickinson | 2009-11-23 16:27:17 +0000 (Mon, 23 Nov 2009) | 9 lines Merged revisions 76456 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76456 | mark.dickinson | 2009-11-23 16:23:43 +0000 (Mon, 23 Nov 2009) | 2 lines Issue #7379: Fix incorrect doctest for Fraction.limit_denominator. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/fractions.py Modified: python/branches/release31-maint/Lib/fractions.py ============================================================================== --- python/branches/release31-maint/Lib/fractions.py (original) +++ python/branches/release31-maint/Lib/fractions.py Mon Nov 23 17:28:18 2009 @@ -162,8 +162,8 @@ Fraction(22, 7) >>> Fraction('3.141592653589793').limit_denominator(100) Fraction(311, 99) - >>> Fraction(1234, 5678).limit_denominator(10000) - Fraction(1234, 5678) + >>> Fraction(4321, 8765).limit_denominator(10000) + Fraction(4321, 8765) """ # Algorithm notes: For any real number x, define a *best upper From python-checkins at python.org Mon Nov 23 17:39:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:39:06 -0000 Subject: [Python-checkins] r76460 - python/trunk/Doc/tutorial/controlflow.rst Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:39:05 2009 New Revision: 76460 Log: Issue #7369: Fibonacci series should start at 0 in tutorial example. Modified: python/trunk/Doc/tutorial/controlflow.rst Modified: python/trunk/Doc/tutorial/controlflow.rst ============================================================================== --- python/trunk/Doc/tutorial/controlflow.rst (original) +++ python/trunk/Doc/tutorial/controlflow.rst Mon Nov 23 17:39:05 2009 @@ -194,13 +194,13 @@ >>> def fib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 - ... while b < n: - ... print b, + ... while a < n: + ... print a, ... a, b = b, a+b ... >>> # Now call the function we just defined: ... fib(2000) - 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 + 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 .. index:: single: documentation strings @@ -244,7 +244,7 @@ >>> f = fib >>> f(100) - 1 1 2 3 5 8 13 21 34 55 89 + 0 1 1 2 3 5 8 13 21 34 55 89 Coming from other languages, you might object that ``fib`` is not a function but a procedure since it doesn't return a value. In fact, even functions without a @@ -264,14 +264,14 @@ ... """Return a list containing the Fibonacci series up to n.""" ... result = [] ... a, b = 0, 1 - ... while b < n: - ... result.append(b) # see below + ... while a < n: + ... result.append(a) # see below ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # call it >>> f100 # write the result - [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] This example, as usual, demonstrates some new Python features: @@ -279,7 +279,7 @@ :keyword:`return` without an expression argument returns ``None``. Falling off the end of a function also returns ``None``. -* The statement ``result.append(b)`` calls a *method* of the list object +* The statement ``result.append(a)`` calls a *method* of the list object ``result``. A method is a function that 'belongs' to an object and is named ``obj.methodname``, where ``obj`` is some object (this may be an expression), and ``methodname`` is the name of a method that is defined by the object's type. @@ -288,7 +288,7 @@ object types and methods, using *classes*, see :ref:`tut-classes`) The method :meth:`append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to - ``result = result + [b]``, but more efficient. + ``result = result + [a]``, but more efficient. .. _tut-defining: From python-checkins at python.org Mon Nov 23 17:39:46 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:39:46 -0000 Subject: [Python-checkins] r76461 - in python/branches/release26-maint: Doc/tutorial/controlflow.rst Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:39:46 2009 New Revision: 76461 Log: Merged revisions 76460 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76460 | mark.dickinson | 2009-11-23 16:39:05 +0000 (Mon, 23 Nov 2009) | 2 lines Issue #7369: Fibonacci series should start at 0 in tutorial example. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/tutorial/controlflow.rst Modified: python/branches/release26-maint/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/controlflow.rst (original) +++ python/branches/release26-maint/Doc/tutorial/controlflow.rst Mon Nov 23 17:39:46 2009 @@ -194,13 +194,13 @@ >>> def fib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 - ... while b < n: - ... print b, + ... while a < n: + ... print a, ... a, b = b, a+b ... >>> # Now call the function we just defined: ... fib(2000) - 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 + 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 .. index:: single: documentation strings @@ -244,7 +244,7 @@ >>> f = fib >>> f(100) - 1 1 2 3 5 8 13 21 34 55 89 + 0 1 1 2 3 5 8 13 21 34 55 89 Coming from other languages, you might object that ``fib`` is not a function but a procedure since it doesn't return a value. In fact, even functions without a @@ -264,14 +264,14 @@ ... """Return a list containing the Fibonacci series up to n.""" ... result = [] ... a, b = 0, 1 - ... while b < n: - ... result.append(b) # see below + ... while a < n: + ... result.append(a) # see below ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # call it >>> f100 # write the result - [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] This example, as usual, demonstrates some new Python features: @@ -279,7 +279,7 @@ :keyword:`return` without an expression argument returns ``None``. Falling off the end of a function also returns ``None``. -* The statement ``result.append(b)`` calls a *method* of the list object +* The statement ``result.append(a)`` calls a *method* of the list object ``result``. A method is a function that 'belongs' to an object and is named ``obj.methodname``, where ``obj`` is some object (this may be an expression), and ``methodname`` is the name of a method that is defined by the object's type. @@ -288,7 +288,7 @@ object types and methods, using *classes*, see :ref:`tut-classes`) The method :meth:`append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to - ``result = result + [b]``, but more efficient. + ``result = result + [a]``, but more efficient. .. _tut-defining: From python-checkins at python.org Mon Nov 23 17:41:42 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:41:42 -0000 Subject: [Python-checkins] r76462 - in python/branches/py3k: Doc/tutorial/controlflow.rst Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:41:41 2009 New Revision: 76462 Log: Merged revisions 76460 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76460 | mark.dickinson | 2009-11-23 16:39:05 +0000 (Mon, 23 Nov 2009) | 2 lines Issue #7369: Fibonacci series should start at 0 in tutorial example. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/tutorial/controlflow.rst Modified: python/branches/py3k/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/controlflow.rst (original) +++ python/branches/py3k/Doc/tutorial/controlflow.rst Mon Nov 23 17:41:41 2009 @@ -225,14 +225,14 @@ >>> def fib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 - ... while b < n: - ... print(b, end=' ') + ... while a < n: + ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # Now call the function we just defined: ... fib(2000) - 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 + 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 .. index:: single: documentation strings @@ -276,7 +276,7 @@ >>> f = fib >>> f(100) - 1 1 2 3 5 8 13 21 34 55 89 + 0 1 1 2 3 5 8 13 21 34 55 89 Coming from other languages, you might object that ``fib`` is not a function but a procedure since it doesn't return a value. In fact, even functions without a @@ -296,14 +296,14 @@ ... """Return a list containing the Fibonacci series up to n.""" ... result = [] ... a, b = 0, 1 - ... while b < n: - ... result.append(b) # see below + ... while a < n: + ... result.append(a) # see below ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # call it >>> f100 # write the result - [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] This example, as usual, demonstrates some new Python features: @@ -311,7 +311,7 @@ :keyword:`return` without an expression argument returns ``None``. Falling off the end of a function also returns ``None``. -* The statement ``result.append(b)`` calls a *method* of the list object +* The statement ``result.append(a)`` calls a *method* of the list object ``result``. A method is a function that 'belongs' to an object and is named ``obj.methodname``, where ``obj`` is some object (this may be an expression), and ``methodname`` is the name of a method that is defined by the object's type. @@ -320,7 +320,7 @@ object types and methods, using *classes*, see :ref:`tut-classes`) The method :meth:`append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to - ``result = result + [b]``, but more efficient. + ``result = result + [a]``, but more efficient. .. _tut-defining: From python-checkins at python.org Mon Nov 23 17:42:35 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 16:42:35 -0000 Subject: [Python-checkins] r76463 - in python/branches/release31-maint: Doc/tutorial/controlflow.rst Message-ID: Author: mark.dickinson Date: Mon Nov 23 17:42:35 2009 New Revision: 76463 Log: Merged revisions 76462 via svnmerge from svn+ssh://pythondev at www.python.org/python/branches/py3k ................ r76462 | mark.dickinson | 2009-11-23 16:41:41 +0000 (Mon, 23 Nov 2009) | 9 lines Merged revisions 76460 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76460 | mark.dickinson | 2009-11-23 16:39:05 +0000 (Mon, 23 Nov 2009) | 2 lines Issue #7369: Fibonacci series should start at 0 in tutorial example. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/tutorial/controlflow.rst Modified: python/branches/release31-maint/Doc/tutorial/controlflow.rst ============================================================================== --- python/branches/release31-maint/Doc/tutorial/controlflow.rst (original) +++ python/branches/release31-maint/Doc/tutorial/controlflow.rst Mon Nov 23 17:42:35 2009 @@ -225,14 +225,14 @@ >>> def fib(n): # write Fibonacci series up to n ... """Print a Fibonacci series up to n.""" ... a, b = 0, 1 - ... while b < n: - ... print(b, end=' ') + ... while a < n: + ... print(a, end=' ') ... a, b = b, a+b ... print() ... >>> # Now call the function we just defined: ... fib(2000) - 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 + 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 .. index:: single: documentation strings @@ -276,7 +276,7 @@ >>> f = fib >>> f(100) - 1 1 2 3 5 8 13 21 34 55 89 + 0 1 1 2 3 5 8 13 21 34 55 89 Coming from other languages, you might object that ``fib`` is not a function but a procedure since it doesn't return a value. In fact, even functions without a @@ -296,14 +296,14 @@ ... """Return a list containing the Fibonacci series up to n.""" ... result = [] ... a, b = 0, 1 - ... while b < n: - ... result.append(b) # see below + ... while a < n: + ... result.append(a) # see below ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # call it >>> f100 # write the result - [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] This example, as usual, demonstrates some new Python features: @@ -311,7 +311,7 @@ :keyword:`return` without an expression argument returns ``None``. Falling off the end of a function also returns ``None``. -* The statement ``result.append(b)`` calls a *method* of the list object +* The statement ``result.append(a)`` calls a *method* of the list object ``result``. A method is a function that 'belongs' to an object and is named ``obj.methodname``, where ``obj`` is some object (this may be an expression), and ``methodname`` is the name of a method that is defined by the object's type. @@ -320,7 +320,7 @@ object types and methods, using *classes*, see :ref:`tut-classes`) The method :meth:`append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to - ``result = result + [b]``, but more efficient. + ``result = result + [a]``, but more efficient. .. _tut-defining: From python-checkins at python.org Mon Nov 23 19:41:32 2009 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 23 Nov 2009 18:41:32 -0000 Subject: [Python-checkins] r76464 - in python/trunk: Lib/difflib.py Lib/test/test_difflib.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Mon Nov 23 19:41:31 2009 New Revision: 76464 Log: Fix for issue1488943 - difflib.Differ() doesn't always add hints for tab characters. Modified: python/trunk/Lib/difflib.py python/trunk/Lib/test/test_difflib.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/difflib.py ============================================================================== --- python/trunk/Lib/difflib.py (original) +++ python/trunk/Lib/difflib.py Mon Nov 23 19:41:31 2009 @@ -1061,20 +1061,21 @@ Example: >>> d = Differ() - >>> results = d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n', - ... ' ^ ^ ^ ', '+ ^ ^ ^ ') + >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n', + ... ' ^ ^ ^ ', ' ^ ^ ^ ') >>> for line in results: print repr(line) ... '- \tabcDefghiJkl\n' '? \t ^ ^ ^\n' - '+ \t\tabcdefGhijkl\n' - '? \t ^ ^ ^\n' + '+ \tabcdefGhijkl\n' + '? \t ^ ^ ^\n' """ # Can hurt, but will probably help most of the time. common = min(_count_leading(aline, "\t"), _count_leading(bline, "\t")) common = min(common, _count_leading(atags[:common], " ")) + common = min(common, _count_leading(btags[:common], " ")) atags = atags[common:].rstrip() btags = btags[common:].rstrip() Modified: python/trunk/Lib/test/test_difflib.py ============================================================================== --- python/trunk/Lib/test/test_difflib.py (original) +++ python/trunk/Lib/test/test_difflib.py Mon Nov 23 19:41:31 2009 @@ -20,6 +20,14 @@ diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, diff_gen.next) + def test_added_tab_hint(self): + # Check fix for bug #1488943 + diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) + self.assertEqual("- \tI am a buggy", diff[0]) + self.assertEqual("? --\n", diff[1]) + self.assertEqual("+ \t\tI am a bug", diff[2]) + self.assertEqual("? +\n", diff[3]) + patch914575_from1 = """ 1. Beautiful is beTTer than ugly. 2. Explicit is better than implicit. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Nov 23 19:41:31 2009 @@ -476,6 +476,8 @@ Library ------- +- Issue #1488943: difflib.Differ() doesn't always add hints for tab characters + - Issue #6123: tarfile now opens empty archives correctly and consistently raises ReadError on empty files. From python-checkins at python.org Mon Nov 23 19:46:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 18:46:41 -0000 Subject: [Python-checkins] r76465 - in python/trunk: Lib/test/string_tests.py Misc/NEWS Objects/stringobject.c Objects/unicodeobject.c Message-ID: Author: mark.dickinson Date: Mon Nov 23 19:46:41 2009 New Revision: 76465 Log: Remove restriction on precision when formatting floats. This is the first step towards removing the %f -> %g switch (see issues 7117, 5859). Modified: python/trunk/Lib/test/string_tests.py python/trunk/Misc/NEWS python/trunk/Objects/stringobject.c python/trunk/Objects/unicodeobject.c Modified: python/trunk/Lib/test/string_tests.py ============================================================================== --- python/trunk/Lib/test/string_tests.py (original) +++ python/trunk/Lib/test/string_tests.py Mon Nov 23 19:46:41 2009 @@ -1090,14 +1090,7 @@ value = 0.01 for x in xrange(60): value = value * 3.141592655 / 3.0 * 10.0 - # The formatfloat() code in stringobject.c and - # unicodeobject.c uses a 120 byte buffer and switches from - # 'f' formatting to 'g' at precision 50, so we expect - # OverflowErrors for the ranges x < 50 and prec >= 67. - if x < 50 and prec >= 67: - self.checkraises(OverflowError, format, "__mod__", value) - else: - self.checkcall(format, "__mod__", value) + self.checkcall(format, "__mod__", value) def test_inplace_rewrites(self): # Check that strings don't copy and modify cached single-character strings Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Nov 23 19:46:41 2009 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Remove restrictions on precision when formatting floats. E.g., + "%.120g" % 1e-100 used to raise OverflowError, but now gives the + requested 120 significant digits instead. + - Add Py3k warnings for parameter names in parenthesis. - Issue #7362: Give a proper error message for def f((x)=3): pass. Modified: python/trunk/Objects/stringobject.c ============================================================================== --- python/trunk/Objects/stringobject.c (original) +++ python/trunk/Objects/stringobject.c Mon Nov 23 19:46:41 2009 @@ -4379,72 +4379,36 @@ #define F_ALT (1<<3) #define F_ZERO (1<<4) -Py_LOCAL_INLINE(int) -formatfloat(char *buf, size_t buflen, int flags, - int prec, int type, PyObject *v) +/* Returns a new reference to a PyString object, or NULL on failure. */ + +static PyObject * +formatfloat(PyObject *v, int flags, int prec, int type) { - char *tmp; + char *p; + PyObject *result; double x; - Py_ssize_t len; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "float argument required, " "not %.200s", Py_TYPE(v)->tp_name); - return -1; + return NULL; } + if (prec < 0) prec = 6; -#if SIZEOF_INT > 4 - /* make sure that the decimal representation of precision really does - need at most 10 digits: platforms with sizeof(int) == 8 exist! */ - if (prec > 0x7fffffff) { - PyErr_SetString(PyExc_OverflowError, - "outrageously large precision " - "for formatted float"); - return -1; - } -#endif if (type == 'f' && fabs(x) >= 1e50) type = 'g'; - /* Worst case length calc to ensure no buffer overrun: - 'g' formats: - fmt = %#.g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec - - 'f' formats: - buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) - len = 1 + 50 + 1 + prec = 52 + prec - - If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase the length by one. - - */ - if (((type == 'g' || type == 'G') && - buflen <= (size_t)10 + (size_t)prec) || - (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { - PyErr_SetString(PyExc_OverflowError, - "formatted float is too long (precision too large?)"); - return -1; - } - tmp = PyOS_double_to_string(x, type, prec, - (flags&F_ALT)?Py_DTSF_ALT:0, NULL); - if (!tmp) - return -1; - len = strlen(tmp); - if (len >= buflen) { - PyErr_SetString(PyExc_OverflowError, - "formatted float is too long (precision too large?)"); - PyMem_Free(tmp); - return -1; - } - strcpy(buf, tmp); - PyMem_Free(tmp); - return (int)len; + p = PyOS_double_to_string(x, type, prec, + (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); + + if (p == NULL) + return NULL; + result = PyString_FromStringAndSize(p, strlen(p)); + PyMem_Free(p); + return result; } /* _PyString_FormatLong emulates the format codes d, u, o, x and X, and @@ -4684,7 +4648,7 @@ /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) - FORMATBUFLEN is the length of the buffer in which the floats, ints, & + FORMATBUFLEN is the length of the buffer in which the ints & chars are formatted. XXX This is a magic number. Each formatting routine does bounds checking to ensure no overflow, but a better solution may be to malloc a buffer of appropriate size for each @@ -4754,7 +4718,7 @@ int sign; Py_ssize_t len; char formatbuf[FORMATBUFLEN]; - /* For format{float,int,char}() */ + /* For format{int,char}() */ #ifdef Py_USING_UNICODE char *fmt_start = fmt; Py_ssize_t argidx_start = argidx; @@ -5007,11 +4971,11 @@ case 'G': if (c == 'F') c = 'f'; - pbuf = formatbuf; - len = formatfloat(pbuf, sizeof(formatbuf), - flags, prec, c, v); - if (len < 0) + temp = formatfloat(v, flags, prec, c); + if (temp == NULL) goto error; + pbuf = PyString_AS_STRING(temp); + len = PyString_GET_SIZE(temp); sign = 1; if (flags & F_ZERO) fill = '0'; Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Mon Nov 23 19:46:41 2009 @@ -8302,68 +8302,32 @@ shared with stringobject.c, converting from 8-bit to Unicode after the formatting is done. */ -static int -formatfloat(Py_UNICODE *buf, - size_t buflen, - int flags, - int prec, - int type, - PyObject *v) +/* Returns a new reference to a PyUnicode object, or NULL on failure. */ + +static PyObject * +formatfloat(PyObject *v, int flags, int prec, int type) { + char *p; + PyObject *result; double x; - Py_ssize_t result; - char *tmp; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) - return -1; + return NULL; + if (prec < 0) prec = 6; -#if SIZEOF_INT > 4 - /* make sure that the decimal representation of precision really does - need at most 10 digits: platforms with sizeof(int) == 8 exist! */ - if (prec > 0x7fffffff) { - PyErr_SetString(PyExc_OverflowError, - "outrageously large precision " - "for formatted float"); - return -1; - } -#endif if (type == 'f' && fabs(x) >= 1e50) type = 'g'; - /* Worst case length calc to ensure no buffer overrun: - 'g' formats: - fmt = %#.g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec - - 'f' formats: - buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) - len = 1 + 50 + 1 + prec = 52 + prec - - If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase the length by one. - - */ - if (((type == 'g' || type == 'G') && - buflen <= (size_t)10 + (size_t)prec) || - (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { - PyErr_SetString(PyExc_OverflowError, - "formatted float is too long (precision too large?)"); - return -1; - } - - tmp = PyOS_double_to_string(x, type, prec, - (flags&F_ALT)?Py_DTSF_ALT:0, NULL); - if (!tmp) - return -1; - - result = strtounicode(buf, tmp); - PyMem_Free(tmp); - return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); + p = PyOS_double_to_string(x, type, prec, + (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); + if (p == NULL) + return NULL; + result = PyUnicode_FromStringAndSize(p, strlen(p)); + PyMem_Free(p); + return result; } static PyObject* @@ -8516,7 +8480,7 @@ /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) - FORMATBUFLEN is the length of the buffer in which the floats, ints, & + FORMATBUFLEN is the length of the buffer in which the ints & chars are formatted. XXX This is a magic number. Each formatting routine does bounds checking to ensure no overflow, but a better solution may be to malloc a buffer of appropriate size for each @@ -8587,7 +8551,7 @@ Py_UNICODE *pbuf; Py_UNICODE sign; Py_ssize_t len; - Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */ + Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{int,char}() */ fmt++; if (*fmt == '(') { @@ -8850,11 +8814,11 @@ case 'G': if (c == 'F') c = 'f'; - pbuf = formatbuf; - len = formatfloat(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE), - flags, prec, c, v); - if (len < 0) + temp = formatfloat(v, flags, prec, c); + if (temp == NULL) goto onError; + pbuf = PyUnicode_AS_UNICODE(temp); + len = PyUnicode_GET_SIZE(temp); sign = 1; if (flags & F_ZERO) fill = '0'; From python-checkins at python.org Mon Nov 23 19:49:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 18:49:29 -0000 Subject: [Python-checkins] r76466 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Nov 23 19:49:28 2009 New Revision: 76466 Log: Blocked revisions 76465 via svnmerge ........ r76465 | mark.dickinson | 2009-11-23 18:46:41 +0000 (Mon, 23 Nov 2009) | 4 lines Remove restriction on precision when formatting floats. This is the first step towards removing the %f -> %g switch (see issues 7117, 5859). ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 23 19:52:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 18:52:37 -0000 Subject: [Python-checkins] r76467 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Nov 23 19:52:36 2009 New Revision: 76467 Log: Blocked revisions 76465 via svnmerge ........ r76465 | mark.dickinson | 2009-11-23 18:46:41 +0000 (Mon, 23 Nov 2009) | 4 lines Remove restriction on precision when formatting floats. This is the first step towards removing the %f -> %g switch (see issues 7117, 5859). ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Nov 23 19:54:34 2009 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 23 Nov 2009 18:54:34 -0000 Subject: [Python-checkins] r76468 - in python/branches/release26-maint: Lib/difflib.py Lib/test/test_difflib.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Mon Nov 23 19:54:33 2009 New Revision: 76468 Log: Merged revisions 76464 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76464 | senthil.kumaran | 2009-11-24 00:11:31 +0530 (Tue, 24 Nov 2009) | 4 lines Fix for issue1488943 - difflib.Differ() doesn't always add hints for tab characters. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/difflib.py python/branches/release26-maint/Lib/test/test_difflib.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/difflib.py ============================================================================== --- python/branches/release26-maint/Lib/difflib.py (original) +++ python/branches/release26-maint/Lib/difflib.py Mon Nov 23 19:54:33 2009 @@ -1061,20 +1061,21 @@ Example: >>> d = Differ() - >>> results = d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n', - ... ' ^ ^ ^ ', '+ ^ ^ ^ ') + >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n', + ... ' ^ ^ ^ ', ' ^ ^ ^ ') >>> for line in results: print repr(line) ... '- \tabcDefghiJkl\n' '? \t ^ ^ ^\n' - '+ \t\tabcdefGhijkl\n' - '? \t ^ ^ ^\n' + '+ \tabcdefGhijkl\n' + '? \t ^ ^ ^\n' """ # Can hurt, but will probably help most of the time. common = min(_count_leading(aline, "\t"), _count_leading(bline, "\t")) common = min(common, _count_leading(atags[:common], " ")) + common = min(common, _count_leading(btags[:common], " ")) atags = atags[common:].rstrip() btags = btags[common:].rstrip() Modified: python/branches/release26-maint/Lib/test/test_difflib.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_difflib.py (original) +++ python/branches/release26-maint/Lib/test/test_difflib.py Mon Nov 23 19:54:33 2009 @@ -20,6 +20,14 @@ diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, diff_gen.next) + def test_added_tab_hint(self): + # Check fix for bug #1488943 + diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) + self.assertEqual("- \tI am a buggy", diff[0]) + self.assertEqual("? --\n", diff[1]) + self.assertEqual("+ \t\tI am a bug", diff[2]) + self.assertEqual("? +\n", diff[3]) + patch914575_from1 = """ 1. Beautiful is beTTer than ugly. 2. Explicit is better than implicit. Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Nov 23 19:54:33 2009 @@ -258,6 +258,8 @@ Library ------- +- Issue #1488943: difflib.Differ() doesn't always add hints for tab characters + - Issue #5037: Proxy the __unicode__ special method instead to __unicode__ instead of __str__. From python-checkins at python.org Mon Nov 23 20:02:52 2009 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 23 Nov 2009 19:02:52 -0000 Subject: [Python-checkins] r76469 - in python/branches/py3k: Lib/difflib.py Lib/test/test_difflib.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Mon Nov 23 20:02:52 2009 New Revision: 76469 Log: Merged revisions 76464 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76464 | senthil.kumaran | 2009-11-24 00:11:31 +0530 (Tue, 24 Nov 2009) | 4 lines Fix for issue1488943 - difflib.Differ() doesn't always add hints for tab characters. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/difflib.py python/branches/py3k/Lib/test/test_difflib.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/difflib.py ============================================================================== --- python/branches/py3k/Lib/difflib.py (original) +++ python/branches/py3k/Lib/difflib.py Mon Nov 23 20:02:52 2009 @@ -1060,20 +1060,21 @@ Example: >>> d = Differ() - >>> results = d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n', - ... ' ^ ^ ^ ', '+ ^ ^ ^ ') + >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n', + ... ' ^ ^ ^ ', ' ^ ^ ^ ') >>> for line in results: print(repr(line)) ... '- \tabcDefghiJkl\n' '? \t ^ ^ ^\n' - '+ \t\tabcdefGhijkl\n' - '? \t ^ ^ ^\n' + '+ \tabcdefGhijkl\n' + '? \t ^ ^ ^\n' """ # Can hurt, but will probably help most of the time. common = min(_count_leading(aline, "\t"), _count_leading(bline, "\t")) common = min(common, _count_leading(atags[:common], " ")) + common = min(common, _count_leading(btags[:common], " ")) atags = atags[common:].rstrip() btags = btags[common:].rstrip() Modified: python/branches/py3k/Lib/test/test_difflib.py ============================================================================== --- python/branches/py3k/Lib/test/test_difflib.py (original) +++ python/branches/py3k/Lib/test/test_difflib.py Mon Nov 23 20:02:52 2009 @@ -20,6 +20,14 @@ diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, next, diff_gen) + def test_added_tab_hint(self): + # Check fix for bug #1488943 + diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) + self.assertEqual("- \tI am a buggy", diff[0]) + self.assertEqual("? --\n", diff[1]) + self.assertEqual("+ \t\tI am a bug", diff[2]) + self.assertEqual("? +\n", diff[3]) + patch914575_from1 = """ 1. Beautiful is beTTer than ugly. 2. Explicit is better than implicit. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 23 20:02:52 2009 @@ -140,6 +140,8 @@ Library ------- +- Issue #1488943: difflib.Differ() doesn't always add hints for tab characters + - Issue #6123: tarfile now opens empty archives correctly and consistently raises ReadError on empty files. From python-checkins at python.org Mon Nov 23 20:06:12 2009 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 23 Nov 2009 19:06:12 -0000 Subject: [Python-checkins] r76470 - in python/branches/release31-maint: Lib/difflib.py Lib/test/test_difflib.py Misc/NEWS Message-ID: Author: senthil.kumaran Date: Mon Nov 23 20:06:11 2009 New Revision: 76470 Log: Merged revisions 76469 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76469 | senthil.kumaran | 2009-11-24 00:32:52 +0530 (Tue, 24 Nov 2009) | 10 lines Merged revisions 76464 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76464 | senthil.kumaran | 2009-11-24 00:11:31 +0530 (Tue, 24 Nov 2009) | 4 lines Fix for issue1488943 - difflib.Differ() doesn't always add hints for tab characters. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/difflib.py python/branches/release31-maint/Lib/test/test_difflib.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/difflib.py ============================================================================== --- python/branches/release31-maint/Lib/difflib.py (original) +++ python/branches/release31-maint/Lib/difflib.py Mon Nov 23 20:06:11 2009 @@ -1060,20 +1060,21 @@ Example: >>> d = Differ() - >>> results = d._qformat('\tabcDefghiJkl\n', '\t\tabcdefGhijkl\n', - ... ' ^ ^ ^ ', '+ ^ ^ ^ ') + >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n', + ... ' ^ ^ ^ ', ' ^ ^ ^ ') >>> for line in results: print(repr(line)) ... '- \tabcDefghiJkl\n' '? \t ^ ^ ^\n' - '+ \t\tabcdefGhijkl\n' - '? \t ^ ^ ^\n' + '+ \tabcdefGhijkl\n' + '? \t ^ ^ ^\n' """ # Can hurt, but will probably help most of the time. common = min(_count_leading(aline, "\t"), _count_leading(bline, "\t")) common = min(common, _count_leading(atags[:common], " ")) + common = min(common, _count_leading(btags[:common], " ")) atags = atags[common:].rstrip() btags = btags[common:].rstrip() Modified: python/branches/release31-maint/Lib/test/test_difflib.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_difflib.py (original) +++ python/branches/release31-maint/Lib/test/test_difflib.py Mon Nov 23 20:06:11 2009 @@ -20,6 +20,14 @@ diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, next, diff_gen) + def test_added_tab_hint(self): + # Check fix for bug #1488943 + diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) + self.assertEqual("- \tI am a buggy", diff[0]) + self.assertEqual("? --\n", diff[1]) + self.assertEqual("+ \t\tI am a bug", diff[2]) + self.assertEqual("? +\n", diff[3]) + patch914575_from1 = """ 1. Beautiful is beTTer than ugly. 2. Explicit is better than implicit. Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Nov 23 20:06:11 2009 @@ -49,6 +49,8 @@ Library ------- +- Issue #1488943: difflib.Differ() doesn't always add hints for tab characters + - Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can be 2. From python-checkins at python.org Mon Nov 23 20:53:20 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 23 Nov 2009 19:53:20 -0000 Subject: [Python-checkins] r76471 - python/trunk/Doc/library/calendar.rst Message-ID: Author: georg.brandl Date: Mon Nov 23 20:53:19 2009 New Revision: 76471 Log: #7345: fix arguments of formatyear(). Modified: python/trunk/Doc/library/calendar.rst Modified: python/trunk/Doc/library/calendar.rst ============================================================================== --- python/trunk/Doc/library/calendar.rst (original) +++ python/trunk/Doc/library/calendar.rst Mon Nov 23 20:53:19 2009 @@ -129,7 +129,7 @@ Print a month's calendar as returned by :meth:`formatmonth`. - .. method:: formatyear(theyear, themonth[, w[, l[, c[, m]]]]) + .. method:: formatyear(theyear[, w[, l[, c[, m]]]]) Return a *m*-column calendar for an entire year as a multi-line string. Optional parameters *w*, *l*, and *c* are for date column width, lines per @@ -160,7 +160,7 @@ used. - .. method:: formatyear(theyear, themonth[, width]) + .. method:: formatyear(theyear[, width]) Return a year's calendar as an HTML table. *width* (defaulting to 3) specifies the number of months per row. From python-checkins at python.org Mon Nov 23 21:54:09 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 20:54:09 -0000 Subject: [Python-checkins] r76472 - in python/trunk: Doc/library/stdtypes.rst Lib/test/test_types.py Misc/NEWS Objects/stringlib/formatter.h Objects/stringobject.c Objects/unicodeobject.c Message-ID: Author: mark.dickinson Date: Mon Nov 23 21:54:09 2009 New Revision: 76472 Log: Issue #7117, continued: Remove substitution of %g-style formatting for %f-style formatting, which used to occur at high precision. Float formatting should now be consistent between 2.7 and 3.1. Modified: python/trunk/Doc/library/stdtypes.rst python/trunk/Lib/test/test_types.py python/trunk/Misc/NEWS python/trunk/Objects/stringlib/formatter.h python/trunk/Objects/stringobject.c python/trunk/Objects/unicodeobject.c Modified: python/trunk/Doc/library/stdtypes.rst ============================================================================== --- python/trunk/Doc/library/stdtypes.rst (original) +++ python/trunk/Doc/library/stdtypes.rst Mon Nov 23 21:54:09 2009 @@ -1453,9 +1453,9 @@ .. XXX Examples? -For safety reasons, floating point precisions are clipped to 50; ``%f`` -conversions for numbers whose absolute value is over 1e50 are replaced by ``%g`` -conversions. [#]_ All other errors raise exceptions. +.. versionchanged:: 2.7 + ``%f`` conversions for numbers whose absolute value is over 1e50 are no + longer replaced by ``%g`` conversions. .. index:: module: string @@ -2875,10 +2875,6 @@ .. [#] To format only a tuple you should therefore provide a singleton tuple whose only element is the tuple to be formatted. -.. [#] These numbers are fairly arbitrary. They are intended to avoid printing endless - strings of meaningless digits without hampering correct use and without having - to know the exact precision of floating point values on a particular machine. - .. [#] The advantage of leaving the newline on is that returning an empty string is then an unambiguous EOF indication. It is also possible (in cases where it might matter, for example, if you want to make an exact copy of a file while Modified: python/trunk/Lib/test/test_types.py ============================================================================== --- python/trunk/Lib/test/test_types.py (original) +++ python/trunk/Lib/test/test_types.py Mon Nov 23 21:54:09 2009 @@ -601,10 +601,25 @@ test(-1.0, ' f', '-1.000000') test( 1.0, '+f', '+1.000000') test(-1.0, '+f', '-1.000000') - test(1.1234e90, 'f', '1.1234e+90') - test(1.1234e90, 'F', '1.1234e+90') - test(1.1234e200, 'f', '1.1234e+200') - test(1.1234e200, 'F', '1.1234e+200') + + # Python versions <= 2.6 switched from 'f' to 'g' formatting for + # values larger than 1e50. No longer. + f = 1.1234e90 + for fmt in 'f', 'F': + # don't do a direct equality check, since on some + # platforms only the first few digits of dtoa + # will be reliable + result = f.__format__(fmt) + self.assertEqual(len(result), 98) + self.assertEqual(result[-7], '.') + self.assertTrue(result[:12] in ('112340000000', '112339999999')) + f = 1.1234e200 + for fmt in 'f', 'F': + result = f.__format__(fmt) + self.assertEqual(len(result), 208) + self.assertEqual(result[-7], '.') + self.assertTrue(result[:12] in ('112340000000', '112339999999')) + test( 1.0, 'e', '1.000000e+00') test(-1.0, 'e', '-1.000000e+00') Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Nov 23 21:54:09 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Remove switch from "%f" formatting to "%g" formatting for floats + larger than 1e50 in absolute value. + - Remove restrictions on precision when formatting floats. E.g., "%.120g" % 1e-100 used to raise OverflowError, but now gives the requested 120 significant digits instead. Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Mon Nov 23 21:54:09 2009 @@ -957,12 +957,6 @@ if (precision < 0) precision = default_precision; -#if PY_VERSION_HEX < 0x03010000 - /* 3.1 no longer converts large 'f' to 'g'. */ - if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) - type = 'g'; -#endif - /* Cast "type", because if we're in unicode we need to pass a 8-bit char. This is safe, because we've restricted what "type" can be. */ Modified: python/trunk/Objects/stringobject.c ============================================================================== --- python/trunk/Objects/stringobject.c (original) +++ python/trunk/Objects/stringobject.c Mon Nov 23 21:54:09 2009 @@ -4398,9 +4398,6 @@ if (prec < 0) prec = 6; - if (type == 'f' && fabs(x) >= 1e50) - type = 'g'; - p = PyOS_double_to_string(x, type, prec, (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Mon Nov 23 21:54:09 2009 @@ -8318,9 +8318,6 @@ if (prec < 0) prec = 6; - if (type == 'f' && fabs(x) >= 1e50) - type = 'g'; - p = PyOS_double_to_string(x, type, prec, (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); if (p == NULL) From python-checkins at python.org Mon Nov 23 21:54:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 20:54:56 -0000 Subject: [Python-checkins] r76473 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Nov 23 21:54:56 2009 New Revision: 76473 Log: Blocked revisions 76472 via svnmerge ........ r76472 | mark.dickinson | 2009-11-23 20:54:09 +0000 (Mon, 23 Nov 2009) | 4 lines Issue #7117, continued: Remove substitution of %g-style formatting for %f-style formatting, which used to occur at high precision. Float formatting should now be consistent between 2.7 and 3.1. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 23 21:55:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 23 Nov 2009 20:55:59 -0000 Subject: [Python-checkins] r76474 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Nov 23 21:55:58 2009 New Revision: 76474 Log: Blocked revisions 76472 via svnmerge ........ r76472 | mark.dickinson | 2009-11-23 20:54:09 +0000 (Mon, 23 Nov 2009) | 4 lines Issue #7117, continued: Remove substitution of %g-style formatting for %f-style formatting, which used to occur at high precision. Float formatting should now be consistent between 2.7 and 3.1. ........ Modified: python/branches/py3k/ (props changed) From nnorwitz at gmail.com Mon Nov 23 22:44:09 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 23 Nov 2009 16:44:09 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091123214409.GA29687@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [877203 refs] From solipsis at pitrou.net Tue Nov 24 00:46:49 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 24 Nov 2009 00:46:49 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76469): sum=695 Message-ID: <20091123234649.A3D3A17715@ns6635.ovh.net> py3k results for svn r76469 (hg cset 2c3db50b4c95) -------------------------------------------------- test_multiprocessing leaked [229, 229, 229] references, sum=687 test_urllib leaked [4, 4, 0] references, sum=8 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogaZbFxq', '-x', 'test_httpservers'] From nnorwitz at gmail.com Tue Nov 24 00:54:26 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 23 Nov 2009 18:54:26 -0500 Subject: [Python-checkins] Python Regression Test Failures all (1) Message-ID: <20091123235426.GA19820@kbk-i386-bb.psfb.org> 345 tests OK. 1 test failed: test_threading_local 27 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 Sleepycat Software: Berkeley DB 4.1.25: (December 19, 2002) Test path prefix: /tmp/z-test_bsddb3-12616 test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_socket test_socketserver test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 39 != 49 test_threadsignals test_time test_timeout test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle sh: line 1: python2.4: command not found sh: line 1: python2.6: command not found test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 345 tests OK. 1 test failed: test_threading_local 27 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [893646 refs] From python-checkins at python.org Tue Nov 24 07:52:40 2009 From: python-checkins at python.org (vinay.sajip) Date: Tue, 24 Nov 2009 06:52:40 -0000 Subject: [Python-checkins] r76475 - peps/trunk/pep-0391.txt Message-ID: Author: vinay.sajip Date: Tue Nov 24 07:52:39 2009 New Revision: 76475 Log: Minor changes, additions and clarifications. Modified: peps/trunk/pep-0391.txt Modified: peps/trunk/pep-0391.txt ============================================================================== --- peps/trunk/pep-0391.txt (original) +++ peps/trunk/pep-0391.txt Tue Nov 24 07:52:39 2009 @@ -305,9 +305,9 @@ custom: (): my.package.MyHandler - alternate: int://handlers.file + alternate: cfg://handlers.file -The literal string ``'int://handlers.file'`` will be resolved in an +The literal string ``'cfg://handlers.file'`` will be resolved in an analogous way to the strings with the ``ext://`` prefix, but looking in the configuration itself rather than the import namespace. The mechanism will allow access by dot or by index, in a similar way to @@ -323,29 +323,29 @@ - dev_team at domain.tld subject: Houston, we have a problem. -in the configuration, the string ``'int://handlers'`` would resolve to -the dict with key ``handlers``, the string ``'int://handlers.email`` +in the configuration, the string ``'cfg://handlers'`` would resolve to +the dict with key ``handlers``, the string ``'cfg://handlers.email`` would resolve to the dict with key ``email`` in the ``handlers`` dict, -and so on. The string ``'int://handlers.email.toaddrs[1]`` would +and so on. The string ``'cfg://handlers.email.toaddrs[1]`` would resolve to ``'dev_team.domain.tld'`` and the string -``'int://handlers.email.toaddrs[0]'`` would resolve to the value +``'cfg://handlers.email.toaddrs[0]'`` would resolve to the value ``'support_team at domain.tld'``. The ``subject`` value could be accessed -using either ``'int://handlers.email.subject'`` or, equivalently, -``'int://handlers.email[subject]'``. The latter form only needs to be +using either ``'cfg://handlers.email.subject'`` or, equivalently, +``'cfg://handlers.email[subject]'``. The latter form only needs to be used if the key contains spaces or non-alphanumeric characters. If an index value consists only of decimal digits, access will be attempted using the corresponding integer value, falling back to the string value if needed. -Given a string ``int://handlers.myhandler.mykey.123``, this will +Given a string ``cfg://handlers.myhandler.mykey.123``, this will resolve to ``config_dict['handlers']['myhandler']['mykey']['123']``. -If the string is specified as ``int://handlers.myhandler.mykey[123]``, +If the string is specified as ``cfg://handlers.myhandler.mykey[123]``, the system will attempt to retrieve the value from -``config_dict['handlers']['myhandler']['mykey'][123]``, ad fall back +``config_dict['handlers']['myhandler']['mykey'][123]``, and fall back to ``config_dict['handlers']['myhandler']['mykey']['123']`` if that fails. -Note: the ``ext`` and ``int`` prefixes are provisional. If better +Note: the ``ext`` and ``cfg`` prefixes are provisional. If better alternatives are suggested during the PEP review process, they will be used. @@ -484,7 +484,11 @@ If the specified value is ``True``, the configuration is processed as described in the section on `Incremental Configuration`_, below. - +* `disable_existing_loggers` - whether any existing loggers are to be + disabled. This setting mirrors the parameter of the same name in + ``fileConfig()``. If absent, this parameter defaults to ``True``. + This value is ignored if `incremental` is ``True``. + A Working Example ----------------- @@ -567,7 +571,7 @@ It's certainly possible to provide incremental configuration by other means, for example making ``dictConfig()`` take an ``incremental`` keyword argument which defaults to ``False``. The reason for -suggesting that a flag in the configuration dict be used is that it +suggesting that a value in the configuration dict be used is that it allows for configurations to be sent over the wire as pickled dicts to a socket listener. Thus, the logging verbosity of a long-running application can be altered over time with no need to stop and From python-checkins at python.org Tue Nov 24 10:14:33 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 09:14:33 -0000 Subject: [Python-checkins] r76476 - in peps/trunk: pep-0345.txt pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 10:14:32 2009 New Revision: 76476 Log: added three fields for the project URLs: Repository-URL, Repository-Browser-URL, Bug-Tracker-URL Modified: peps/trunk/pep-0345.txt peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0345.txt ============================================================================== --- peps/trunk/pep-0345.txt (original) +++ peps/trunk/pep-0345.txt Tue Nov 24 10:14:32 2009 @@ -9,7 +9,7 @@ Content-Type: text/x-rst Created: 28-Apr-2005 Python-Version: 2.5 -Post-History: +Post-History: Replaces: 314 @@ -162,7 +162,7 @@ Maintainer (optional) A string containing the maintainer's name at a minimum; additional contact information may be provided. - + Note that this field is intended for use when a package is being maintained by someone other than the original author: it should be omitted if it is identical to ``Author``. @@ -295,7 +295,7 @@ version numbers, separated by commas. Conditional operators must be one of "<", ">", "<=", ">=", "==", and "!=". Version numbers must be in the format specified in `PEP 386`_. - If no operator is provided with a version, the "==" operator + If no operator is provided with a version, the "==" operator is used by default. Any number of conditional operators can be specified, e.g. @@ -326,7 +326,7 @@ RDBMS bindings for use by a given ORM: each project might declare that it provides ``ORM-bindings``, allowing other projects to depend only on having at most one of them installed. - + A version declaration may be supplied (without a comparison operator); the distribution's version number will be implied if none is specified. Version numbers must be in the format specified in @@ -342,7 +342,7 @@ Each entry contains a string describing a distutils project which this package renders obsolete, meaning that the two packages should not be installed at the same time. - + Version declarations can be supplied. Version numbers must be in the format specified in `PEP 386`_. @@ -387,10 +387,10 @@ A version declaration is a series of conditional operators and version numbers, separated by commas. Conditional operators - must be one of "<", ">", "<=", ">=", "==", and "!=". If no + must be one of "<", ">", "<=", ">=", "==", and "!=". If no operator is provided with a version, the "==" operator is used by default. - Because they refer to non-Python software releases, version numbers + Because they refer to non-Python software releases, version numbers for this field are **not** required to conform to the format specified in `PEP 386`_: they should correspond to the version scheme used by the external dependency. @@ -416,6 +416,31 @@ Copyright: Python Software Foundation, 2005 Copyright: Public Domain + +Repository-URL + A string containing the URL for the project repository. + + Example:: + + Repository-URL: http://svn.python.org/projects/python/trunk/ + + +Repository-Browse-URL + A string containing the URL for the project browsable repository. + + Example:: + + Repository-Browse-URL: http://svn.python.org/view/python/trunk + + +Bug-Tracker-URL + A string containing the URL for the package's bug tracker + + Example:: + + Bug-Tracker-URL: http://bugs.python.org/ + + Version Specifiers ================== @@ -432,13 +457,13 @@ Here are some example of fields using such markers:: - Requires-Dist: pywin32, bar > 1.0; sys.platform == 'win32' + Requires-Dist: pywin32 > 1.0; sys.platform == 'win32' Obsoletes-Dist: pywin31; sys.platform == 'win32' Requires-Dist: foo; os.machine == 'i386' Requires-Dist: bar; python_version == '2.4' or python_version == '2.5' Requires-External: libxslt; 'linux' in sys.platform -These markers are using a micro-language that can be interpreted using a +These markers are using a micro-language that can be interpreted using a function ``interpret_marker`` provided in the ``distutils.util`` module in the stdlib:: @@ -446,7 +471,7 @@ >>> interpret_marker("sys.platform == 'win32'") True -Depending if the execution environment meets the requirements, the function +Depending if the execution environment meets the requirements, the function will return True or False. The micro-language behind this is the simplest possible: it compares only @@ -496,6 +521,9 @@ - Requires-Dist - Provides-Dist - Obsoletes-Dist + - Repository-URL + - Repository-Browser-URL + - Bug-Tracker-URL * Deprecated fields: @@ -532,7 +560,7 @@ Fred Drake, Anthony Baxter and Matthias Klose have all contributed to the ideas presented in this PEP. -Tres Seaver, Jim Fulton, Marc-Andr? Lemburg, Tarek Ziad? and other people at +Tres Seaver, Jim Fulton, Marc-Andr? Lemburg, Tarek Ziad? and other people at the Distutils-SIG have contributed to the new updated version. Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 10:14:32 2009 @@ -283,7 +283,7 @@ be a ``1.2.0-r678`` release. We used ``post`` instead of ``r`` because the ``r`` is ambiguous as to whether it indicates a pre- or post-release. -Last, ``.post456.dev34`` indicates a dev parker for a post release, that sorts +Last, ``.post456.dev34`` indicates a dev marker for a post release, that sorts before a ``.post345`` marker. This can be used to do development versions of post releases. From python-checkins at python.org Tue Nov 24 10:24:36 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 09:24:36 -0000 Subject: [Python-checkins] r76477 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 10:24:35 2009 New Revision: 76477 Log: more motivation text and removed trailing space Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 10:24:35 2009 @@ -12,7 +12,7 @@ Abstract ======== -This PEP proposes the inclusion of a new version comparison system in +This PEP proposes the inclusion of a new version comparison system in Distutils. @@ -25,7 +25,7 @@ These changes are located in PEP 345 [#pep345]_. -The ``Requires-Dist`` field will allow a package to define a dependency on +The ``Requires-Dist`` field will allow a package to define a dependency on another package and optionally restrict this dependency to a set of compatible versions, so one may write:: @@ -34,6 +34,10 @@ This means that the distribution requires ``zope.interface``, as long as its version is superior to ``3.5.0``. +This also means that Python projects will need to follow the same convention +than the tool that will be used to install them, so they are able to compare +versions. + That's why Distutils needs to provide a robust standard and reference version scheme, and an API to provide version comparisons. @@ -48,7 +52,7 @@ In Python there are no real restriction yet on how a project should manage its versions, and how they should be incremented. They are no standard -either, even if they are a few conventions widely used, like having a major +either, even if they are a few conventions widely used, like having a major and a minor revision (1.1, 1.2, etc.). Developers are free to put in the `version` meta-data of their package any @@ -62,7 +66,7 @@ for OS packagers, that need to have stricter conventions. The worst case is when a packager is unable to easily compare the versions he needs to package. -For people that want to go further and use a tool to manage their version +For people that want to go further and use a tool to manage their version numbers, the two major ones are: - The current Distutils system [#distutils]_ @@ -71,7 +75,7 @@ Distutils --------- -Distutils currently provides a `StrictVersion` and a `LooseVersion` class +Distutils currently provides a `StrictVersion` and a `LooseVersion` class that can be used to manage versions. The `LooseVersion` class is quite lax. From Distutils doc:: @@ -280,7 +284,7 @@ The trailing ``.dev123`` is for pre-releases. The ``.post123`` is for post-releases -- which apparently is used by a number of projects out there (e.g. Twisted [#twisted]_). For example *after* a ``1.2.0`` release there might -be a ``1.2.0-r678`` release. We used ``post`` instead of ``r`` because the +be a ``1.2.0-r678`` release. We used ``post`` instead of ``r`` because the ``r`` is ambiguous as to whether it indicates a pre- or post-release. Last, ``.post456.dev34`` indicates a dev marker for a post release, that sorts @@ -344,10 +348,10 @@ to get an equivalent (or close) rational version from this function. This does a number of simple normalizations to the given string, based -on observation of versions currently in use on PyPI. Given a dump of those +on observation of versions currently in use on PyPI. Given a dump of those version during PyCon 2009, 4287 of them: -- 2312 (53.93%) match RationalVersion without change with the automatic +- 2312 (53.93%) match RationalVersion without change with the automatic suggestion - 3474 (81.04%) match when using this suggestion method @@ -391,7 +395,7 @@ Acknowledgments =============== -Trent Mick, Matthias Klose, Phillip Eby, and many people at Pycon and +Trent Mick, Matthias Klose, Phillip Eby, and many people at Pycon and Distutils-SIG. Copyright From nnorwitz at gmail.com Tue Nov 24 10:24:48 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 24 Nov 2009 04:24:48 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091124092448.GA10562@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [877203 refs] From python-checkins at python.org Tue Nov 24 10:46:07 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 09:46:07 -0000 Subject: [Python-checkins] r76478 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 10:46:06 2009 New Revision: 76478 Log: added a usage example of suggest_rational_version Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 10:46:06 2009 @@ -355,6 +355,37 @@ suggestion - 3474 (81.04%) match when using this suggestion method +When a tool needs to work with versions, the best strategy is to use +``suggest_rational_version`` on the versions string. If this function returns +``None``, it means that the provided version is not close enough to the +standard scheme:: + + >>> from verlib import suggest_rational_version, RationalVersion + >>> def validate_version(version): + ... rversion = suggest_rational_version(version) + ... if rversion is None: + ... raise ValueError('Cannot work with %s' % version) + ... return RationalVersion(rversion) + ... + + >>> validate_version('2.4rc1') + RationalVersion('2.4c1') + + >>> validate_version('foo') + Traceback (most recent call last): + ... + ValueError: Cannot work with foo + + >>> validate_version('1.24.33') + RationalVersion('1.24.33c1') + + >>> validate_version('1.24.330pre1') + RationalVersion('1.24.330c1') + + >>> validate_version('2008.12.11') + Traceback (most recent call last): + ... + ValueError: Cannot work with 2008.12.11 References ========== From python-checkins at python.org Tue Nov 24 10:53:28 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 09:53:28 -0000 Subject: [Python-checkins] r76479 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 10:53:27 2009 New Revision: 76479 Log: fixed typo Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 10:53:27 2009 @@ -377,7 +377,7 @@ ValueError: Cannot work with foo >>> validate_version('1.24.33') - RationalVersion('1.24.33c1') + RationalVersion('1.24.33') >>> validate_version('1.24.330pre1') RationalVersion('1.24.330c1') From python-checkins at python.org Tue Nov 24 10:55:53 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 09:55:53 -0000 Subject: [Python-checkins] r76480 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 10:55:52 2009 New Revision: 76480 Log: added a roadmap section Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 10:55:52 2009 @@ -387,6 +387,13 @@ ... ValueError: Cannot work with 2008.12.11 +Roadmap +======= + +Distutils will deprecate its existing versions class in favor of +``RationalVersion``. The ``verlib`` module presented in this PEP will be +renamed to ``version`` and placed into the ``distutils`` package. + References ========== From python-checkins at python.org Tue Nov 24 10:57:15 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 09:57:15 -0000 Subject: [Python-checkins] r76481 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 10:57:14 2009 New Revision: 76481 Log: quoting versions in the exception Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 10:57:14 2009 @@ -364,7 +364,7 @@ >>> def validate_version(version): ... rversion = suggest_rational_version(version) ... if rversion is None: - ... raise ValueError('Cannot work with %s' % version) + ... raise ValueError('Cannot work with "%s"' % version) ... return RationalVersion(rversion) ... @@ -374,7 +374,7 @@ >>> validate_version('foo') Traceback (most recent call last): ... - ValueError: Cannot work with foo + ValueError: Cannot work with "foo" >>> validate_version('1.24.33') RationalVersion('1.24.33') @@ -385,7 +385,7 @@ >>> validate_version('2008.12.11') Traceback (most recent call last): ... - ValueError: Cannot work with 2008.12.11 + ValueError: Cannot work with "2008.12.11" Roadmap ======= From python-checkins at python.org Tue Nov 24 11:23:25 2009 From: python-checkins at python.org (tarek.ziade) Date: Tue, 24 Nov 2009 10:23:25 -0000 Subject: [Python-checkins] r76482 - peps/trunk/pep-0386.txt Message-ID: Author: tarek.ziade Date: Tue Nov 24 11:23:25 2009 New Revision: 76482 Log: wording Modified: peps/trunk/pep-0386.txt Modified: peps/trunk/pep-0386.txt ============================================================================== --- peps/trunk/pep-0386.txt (original) +++ peps/trunk/pep-0386.txt Tue Nov 24 11:23:25 2009 @@ -122,7 +122,7 @@ The `StrictVersion` class is more strict. From the doc:: - Version numbering for anal retentive and software idealists. + Version numbering for meticulous retentive and software idealists. Implements the standard interface for version number classes as described above. A version number consists of two or three dot-separated numeric components, with an optional "pre-release" tag From nnorwitz at gmail.com Tue Nov 24 11:51:55 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 24 Nov 2009 05:51:55 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091124105155.GA10126@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_zipimport_support leaked [25, -25, 25] references, sum=25 Less important issues: ---------------------- From python-checkins at python.org Tue Nov 24 11:54:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 10:54:59 -0000 Subject: [Python-checkins] r76483 - in python/trunk: Lib/test/test_float.py Python/bltinmodule.c Message-ID: Author: mark.dickinson Date: Tue Nov 24 11:54:58 2009 New Revision: 76483 Log: round(0, "ermintrude") succeeded instead of producing a TypeError. Fix this. Modified: python/trunk/Lib/test/test_float.py python/trunk/Python/bltinmodule.c Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Tue Nov 24 11:54:58 2009 @@ -367,6 +367,11 @@ self.assertEqual(round(-INF, n), -INF) self.assertTrue(math.isnan(round(NAN, n))) + self.assertRaises(TypeError, round, INF, 0.0) + self.assertRaises(TypeError, round, -INF, 1.0) + self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer") + self.assertRaises(TypeError, round, -0.0, 1j) + def test_large_n(self): for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]: self.assertEqual(round(123.456, n), 123.456) Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Tue Nov 24 11:54:58 2009 @@ -2130,10 +2130,6 @@ kwlist, &x, &o_ndigits)) return NULL; - /* nans, infinities and zeros round to themselves */ - if (!Py_IS_FINITE(x) || x == 0.0) - return PyFloat_FromDouble(x); - if (o_ndigits == NULL) { /* second argument defaults to 0 */ ndigits = 0; @@ -2145,6 +2141,10 @@ return NULL; } + /* nans, infinities and zeros round to themselves */ + if (!Py_IS_FINITE(x) || x == 0.0) + return PyFloat_FromDouble(x); + /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x always rounds to itself. For ndigits < NDIGITS_MIN, x always rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */ From python-checkins at python.org Tue Nov 24 11:55:38 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 10:55:38 -0000 Subject: [Python-checkins] r76484 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 11:55:38 2009 New Revision: 76484 Log: Blocked revisions 76483 via svnmerge ........ r76483 | mark.dickinson | 2009-11-24 10:54:58 +0000 (Tue, 24 Nov 2009) | 2 lines round(0, "ermintrude") succeeded instead of producing a TypeError. Fix this. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Nov 24 11:59:35 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 10:59:35 -0000 Subject: [Python-checkins] r76485 - in python/branches/py3k: Lib/test/test_float.py Message-ID: Author: mark.dickinson Date: Tue Nov 24 11:59:34 2009 New Revision: 76485 Log: Merged revisions 76483 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76483 | mark.dickinson | 2009-11-24 10:54:58 +0000 (Tue, 24 Nov 2009) | 2 lines round(0, "ermintrude") succeeded instead of producing a TypeError. Fix this. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_float.py Modified: python/branches/py3k/Lib/test/test_float.py ============================================================================== --- python/branches/py3k/Lib/test/test_float.py (original) +++ python/branches/py3k/Lib/test/test_float.py Tue Nov 24 11:59:34 2009 @@ -417,6 +417,10 @@ self.assertRaises(OverflowError, round, INF) self.assertRaises(OverflowError, round, -INF) self.assertRaises(ValueError, round, NAN) + self.assertRaises(TypeError, round, INF, 0.0) + self.assertRaises(TypeError, round, -INF, 1.0) + self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer") + self.assertRaises(TypeError, round, -0.0, 1j) @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") From python-checkins at python.org Tue Nov 24 12:00:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 11:00:21 -0000 Subject: [Python-checkins] r76486 - in python/branches/release31-maint: Lib/test/test_float.py Message-ID: Author: mark.dickinson Date: Tue Nov 24 12:00:21 2009 New Revision: 76486 Log: Merged revisions 76485 via svnmerge from svn+ssh://pythondev at www.python.org/python/branches/py3k ................ r76485 | mark.dickinson | 2009-11-24 10:59:34 +0000 (Tue, 24 Nov 2009) | 9 lines Merged revisions 76483 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76483 | mark.dickinson | 2009-11-24 10:54:58 +0000 (Tue, 24 Nov 2009) | 2 lines round(0, "ermintrude") succeeded instead of producing a TypeError. Fix this. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_float.py Modified: python/branches/release31-maint/Lib/test/test_float.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_float.py (original) +++ python/branches/release31-maint/Lib/test/test_float.py Tue Nov 24 12:00:21 2009 @@ -417,6 +417,10 @@ self.assertRaises(OverflowError, round, INF) self.assertRaises(OverflowError, round, -INF) self.assertRaises(ValueError, round, NAN) + self.assertRaises(TypeError, round, INF, 0.0) + self.assertRaises(TypeError, round, -INF, 1.0) + self.assertRaises(TypeError, round, NAN, "ceci n'est pas un integer") + self.assertRaises(TypeError, round, -0.0, 1j) @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") From python-checkins at python.org Tue Nov 24 15:17:30 2009 From: python-checkins at python.org (jesse.noller) Date: Tue, 24 Nov 2009 14:17:30 -0000 Subject: [Python-checkins] r76487 - python/trunk/Lib/test/test_multiprocessing.py Message-ID: Author: jesse.noller Date: Tue Nov 24 15:17:29 2009 New Revision: 76487 Log: comment out test added in r76438, which caused refleaks Modified: python/trunk/Lib/test/test_multiprocessing.py Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Tue Nov 24 15:17:29 2009 @@ -1723,24 +1723,24 @@ logger.setLevel(level=LOG_LEVEL) -class _TestLoggingProcessName(BaseTestCase): - - def handle(self, record): - assert record.processName == multiprocessing.current_process().name - self.__handled = True - - def test_logging(self): - handler = logging.Handler() - handler.handle = self.handle - self.__handled = False - # Bypass getLogger() and side-effects - logger = logging.getLoggerClass()( - 'multiprocessing.test.TestLoggingProcessName') - logger.addHandler(handler) - logger.propagate = False - - logger.warn('foo') - assert self.__handled +# class _TestLoggingProcessName(BaseTestCase): +# +# def handle(self, record): +# assert record.processName == multiprocessing.current_process().name +# self.__handled = True +# +# def test_logging(self): +# handler = logging.Handler() +# handler.handle = self.handle +# self.__handled = False +# # Bypass getLogger() and side-effects +# logger = logging.getLoggerClass()( +# 'multiprocessing.test.TestLoggingProcessName') +# logger.addHandler(handler) +# logger.propagate = False +# +# logger.warn('foo') +# assert self.__handled # # Test to verify handle verification, see issue 3321 From python-checkins at python.org Tue Nov 24 15:22:24 2009 From: python-checkins at python.org (jesse.noller) Date: Tue, 24 Nov 2009 14:22:24 -0000 Subject: [Python-checkins] r76488 - in python/branches/py3k: Lib/test/test_multiprocessing.py Message-ID: Author: jesse.noller Date: Tue Nov 24 15:22:24 2009 New Revision: 76488 Log: Merged revisions 76487 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76487 | jesse.noller | 2009-11-24 09:17:29 -0500 (Tue, 24 Nov 2009) | 1 line comment out test added in r76438, which caused refleaks ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_multiprocessing.py Modified: python/branches/py3k/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k/Lib/test/test_multiprocessing.py Tue Nov 24 15:22:24 2009 @@ -1724,24 +1724,24 @@ logger.setLevel(level=LOG_LEVEL) -class _TestLoggingProcessName(BaseTestCase): - - def handle(self, record): - assert record.processName == multiprocessing.current_process().name - self.__handled = True - - def test_logging(self): - handler = logging.Handler() - handler.handle = self.handle - self.__handled = False - # Bypass getLogger() and side-effects - logger = logging.getLoggerClass()( - 'multiprocessing.test.TestLoggingProcessName') - logger.addHandler(handler) - logger.propagate = False - - logger.warn('foo') - assert self.__handled +# class _TestLoggingProcessName(BaseTestCase): +# +# def handle(self, record): +# assert record.processName == multiprocessing.current_process().name +# self.__handled = True +# +# def test_logging(self): +# handler = logging.Handler() +# handler.handle = self.handle +# self.__handled = False +# # Bypass getLogger() and side-effects +# logger = logging.getLoggerClass()( +# 'multiprocessing.test.TestLoggingProcessName') +# logger.addHandler(handler) +# logger.propagate = False +# +# logger.warn('foo') +# assert self.__handled # # Test to verify handle verification, see issue 3321 From python-checkins at python.org Tue Nov 24 15:27:03 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 14:27:03 -0000 Subject: [Python-checkins] r76489 - in python/trunk/Doc: faq/design.rst library/decimal.rst library/math.rst library/sqlite3.rst library/turtle.rst tutorial/floatingpoint.rst tutorial/inputoutput.rst tutorial/stdlib2.rst Message-ID: Author: mark.dickinson Date: Tue Nov 24 15:27:02 2009 New Revision: 76489 Log: Fix some documentation examples involving the repr of a float. Modified: python/trunk/Doc/faq/design.rst python/trunk/Doc/library/decimal.rst python/trunk/Doc/library/math.rst python/trunk/Doc/library/sqlite3.rst python/trunk/Doc/library/turtle.rst python/trunk/Doc/tutorial/floatingpoint.rst python/trunk/Doc/tutorial/inputoutput.rst python/trunk/Doc/tutorial/stdlib2.rst Modified: python/trunk/Doc/faq/design.rst ============================================================================== --- python/trunk/Doc/faq/design.rst (original) +++ python/trunk/Doc/faq/design.rst Tue Nov 24 15:27:02 2009 @@ -75,9 +75,9 @@ function prints fewer digits and this often results in the more sensible number that was probably intended:: - >>> 0.2 - 0.20000000000000001 - >>> print 0.2 + >>> 1.1 - 0.9 + 0.20000000000000007 + >>> print 1.1 - 0.9 0.2 One of the consequences of this is that it is error-prone to compare the result Modified: python/trunk/Doc/library/decimal.rst ============================================================================== --- python/trunk/Doc/library/decimal.rst (original) +++ python/trunk/Doc/library/decimal.rst Tue Nov 24 15:27:02 2009 @@ -35,9 +35,9 @@ people learn at school." -- excerpt from the decimal arithmetic specification. * Decimal numbers can be represented exactly. In contrast, numbers like - :const:`1.1` do not have an exact representation in binary floating point. End - users typically would not expect :const:`1.1` to display as - :const:`1.1000000000000001` as it does with binary floating point. + :const:`1.1` and :const:`2.2` do not have an exact representations in binary + floating point. End users typically would not expect ``1.1 + 2.2`` to display + as :const:`3.3000000000000003` as it does with binary floating point. * The exactness carries over into arithmetic. In decimal floating point, ``0.1 + 0.1 + 0.1 - 0.3`` is exactly equal to zero. In binary floating point, the result @@ -193,7 +193,7 @@ >>> str(a) '1.34' >>> float(a) - 1.3400000000000001 + 1.34 >>> round(a, 1) # round() first converts to binary floating point 1.3 >>> int(a) Modified: python/trunk/Doc/library/math.rst ============================================================================== --- python/trunk/Doc/library/math.rst (original) +++ python/trunk/Doc/library/math.rst Tue Nov 24 15:27:02 2009 @@ -90,7 +90,7 @@ loss of precision by tracking multiple intermediate partial sums:: >>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) - 0.99999999999999989 + 0.9999999999999999 >>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) 1.0 Modified: python/trunk/Doc/library/sqlite3.rst ============================================================================== --- python/trunk/Doc/library/sqlite3.rst (original) +++ python/trunk/Doc/library/sqlite3.rst Tue Nov 24 15:27:02 2009 @@ -83,7 +83,7 @@ >>> for row in c: ... print row ... - (u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001) + (u'2006-01-05', u'BUY', u'RHAT', 100, 35.14) (u'2006-03-28', u'BUY', u'IBM', 1000, 45.0) (u'2006-04-06', u'SELL', u'IBM', 500, 53.0) (u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0) @@ -601,7 +601,7 @@ >>> type(r) >>> r - (u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.140000000000001) + (u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14) >>> len(r) 5 >>> r[2] Modified: python/trunk/Doc/library/turtle.rst ============================================================================== --- python/trunk/Doc/library/turtle.rst (original) +++ python/trunk/Doc/library/turtle.rst Tue Nov 24 15:27:02 2009 @@ -875,7 +875,7 @@ >>> tup = (0.2, 0.8, 0.55) >>> turtle.pencolor(tup) >>> turtle.pencolor() - (0.20000000000000001, 0.80000000000000004, 0.5490196078431373) + (0.2, 0.8, 0.5490196078431373) >>> colormode(255) >>> turtle.pencolor() (51, 204, 140) Modified: python/trunk/Doc/tutorial/floatingpoint.rst ============================================================================== --- python/trunk/Doc/tutorial/floatingpoint.rst (original) +++ python/trunk/Doc/tutorial/floatingpoint.rst Tue Nov 24 15:27:02 2009 @@ -115,7 +115,7 @@ ... sum += 0.1 ... >>> sum - 0.99999999999999989 + 0.9999999999999999 Binary floating-point arithmetic holds many surprises like this. The problem with "0.1" is explained in precise detail below, in the "Representation Error" Modified: python/trunk/Doc/tutorial/inputoutput.rst ============================================================================== --- python/trunk/Doc/tutorial/inputoutput.rst (original) +++ python/trunk/Doc/tutorial/inputoutput.rst Tue Nov 24 15:27:02 2009 @@ -49,10 +49,10 @@ 'Hello, world.' >>> repr(s) "'Hello, world.'" - >>> str(0.1) - '0.1' - >>> repr(0.1) - '0.10000000000000001' + >>> str(1.0/7.0) + '0.142857142857' + >>> repr(1.0/7.0) + '0.14285714285714285' >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...' Modified: python/trunk/Doc/tutorial/stdlib2.rst ============================================================================== --- python/trunk/Doc/tutorial/stdlib2.rst (original) +++ python/trunk/Doc/tutorial/stdlib2.rst Tue Nov 24 15:27:02 2009 @@ -362,10 +362,13 @@ becomes significant if the results are rounded to the nearest cent:: >>> from decimal import * - >>> Decimal('0.70') * Decimal('1.05') + >>> x = Decimal('0.70') * Decimal('1.05') + >>> x Decimal('0.7350') - >>> .70 * 1.05 - 0.73499999999999999 + >>> x.quantize(Decimal('0.01')) # round to nearest cent + Decimal('0.74') + >>> round(.70 * 1.05, 2) # same calculation with floats + 0.73 The :class:`Decimal` result keeps a trailing zero, automatically inferring four place significance from multiplicands with two place significance. Decimal From python-checkins at python.org Tue Nov 24 15:27:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 14:27:30 -0000 Subject: [Python-checkins] r76490 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 15:27:30 2009 New Revision: 76490 Log: Blocked revisions 76489 via svnmerge ........ r76489 | mark.dickinson | 2009-11-24 14:27:02 +0000 (Tue, 24 Nov 2009) | 1 line Fix some documentation examples involving the repr of a float. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Nov 24 15:33:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 14:33:29 -0000 Subject: [Python-checkins] r76491 - in python/branches/py3k: Doc/faq/design.rst Message-ID: Author: mark.dickinson Date: Tue Nov 24 15:33:29 2009 New Revision: 76491 Log: Merged revisions 76489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76489 | mark.dickinson | 2009-11-24 14:27:02 +0000 (Tue, 24 Nov 2009) | 1 line Fix some documentation examples involving the repr of a float. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/faq/design.rst Modified: python/branches/py3k/Doc/faq/design.rst ============================================================================== --- python/branches/py3k/Doc/faq/design.rst (original) +++ python/branches/py3k/Doc/faq/design.rst Tue Nov 24 15:33:29 2009 @@ -75,9 +75,9 @@ function prints fewer digits and this often results in the more sensible number that was probably intended:: - >>> 0.2 - 0.20000000000000001 - >>> print 0.2 + >>> 1.1 - 0.9 + 0.20000000000000007 + >>> print(1.1 - 0.9) 0.2 One of the consequences of this is that it is error-prone to compare the result From python-checkins at python.org Tue Nov 24 15:33:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 14:33:53 -0000 Subject: [Python-checkins] r76492 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 15:33:53 2009 New Revision: 76492 Log: Blocked revisions 76491 via svnmerge ................ r76491 | mark.dickinson | 2009-11-24 14:33:29 +0000 (Tue, 24 Nov 2009) | 9 lines Merged revisions 76489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76489 | mark.dickinson | 2009-11-24 14:27:02 +0000 (Tue, 24 Nov 2009) | 1 line Fix some documentation examples involving the repr of a float. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Tue Nov 24 15:35:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 14:35:53 -0000 Subject: [Python-checkins] r76493 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 15:35:53 2009 New Revision: 76493 Log: Unblocked revisions 76491 via svnmerge ................ r76491 | mark.dickinson | 2009-11-24 14:33:29 +0000 (Tue, 24 Nov 2009) | 9 lines Merged revisions 76489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76489 | mark.dickinson | 2009-11-24 14:27:02 +0000 (Tue, 24 Nov 2009) | 1 line Fix some documentation examples involving the repr of a float. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Tue Nov 24 15:36:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 14:36:23 -0000 Subject: [Python-checkins] r76494 - in python/branches/release31-maint: Doc/faq/design.rst Message-ID: Author: mark.dickinson Date: Tue Nov 24 15:36:23 2009 New Revision: 76494 Log: Merged revisions 76491 via svnmerge from svn+ssh://pythondev at www.python.org/python/branches/py3k ................ r76491 | mark.dickinson | 2009-11-24 14:33:29 +0000 (Tue, 24 Nov 2009) | 9 lines Merged revisions 76489 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76489 | mark.dickinson | 2009-11-24 14:27:02 +0000 (Tue, 24 Nov 2009) | 1 line Fix some documentation examples involving the repr of a float. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/faq/design.rst Modified: python/branches/release31-maint/Doc/faq/design.rst ============================================================================== --- python/branches/release31-maint/Doc/faq/design.rst (original) +++ python/branches/release31-maint/Doc/faq/design.rst Tue Nov 24 15:36:23 2009 @@ -75,9 +75,9 @@ function prints fewer digits and this often results in the more sensible number that was probably intended:: - >>> 0.2 - 0.20000000000000001 - >>> print 0.2 + >>> 1.1 - 0.9 + 0.20000000000000007 + >>> print(1.1 - 0.9) 0.2 One of the consequences of this is that it is error-prone to compare the result From python-checkins at python.org Tue Nov 24 16:12:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 15:12:21 -0000 Subject: [Python-checkins] r76495 - python/trunk/Lib/test/formatfloat_testcases.txt Message-ID: Author: mark.dickinson Date: Tue Nov 24 16:12:20 2009 New Revision: 76495 Log: Issue #7117: Update float formatting testcases to match those in py3k. Modified: python/trunk/Lib/test/formatfloat_testcases.txt Modified: python/trunk/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/trunk/Lib/test/formatfloat_testcases.txt (original) +++ python/trunk/Lib/test/formatfloat_testcases.txt Tue Nov 24 16:12:20 2009 @@ -11,7 +11,7 @@ -- precision 0; result should never include a . %.0f 1.5 -> 2 ---%.0f 2.5 -> 2 fails on Windows in 2.7, works in 3.1+. See issue 6198. +%.0f 2.5 -> 2 %.0f 3.5 -> 4 %.0f 0.0 -> 0 %.0f 0.1 -> 0 @@ -21,9 +21,9 @@ %.0f 10.01 -> 10 %.0f 123.456 -> 123 %.0f 1234.56 -> 1235 ---%.0f 1e49 -> 9999999999999999464902769475481793196872414789632 See issue 6198. --- %.0f 1e50 -> 100000000000000007629769841091887003294964970946560 --- %.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 See issue 6198. +%.0f 1e49 -> 9999999999999999464902769475481793196872414789632 +%.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 +%.0f 1e50 -> 100000000000000007629769841091887003294964970946560 -- precision 1 %.1f 0.0001 -> 0.0 @@ -31,7 +31,7 @@ %.1f 0.01 -> 0.0 %.1f 0.04 -> 0.0 %.1f 0.06 -> 0.1 --- %.1f 0.25 -> 0.2 See issue 6198. +%.1f 0.25 -> 0.2 %.1f 0.75 -> 0.8 %.1f 1.4 -> 1.4 %.1f 1.5 -> 1.5 @@ -47,7 +47,7 @@ %.2f 0.004999 -> 0.00 %.2f 0.005001 -> 0.01 %.2f 0.01 -> 0.01 --- %.2f 0.125 -> 0.12 See issue 6198. +%.2f 0.125 -> 0.12 %.2f 0.375 -> 0.38 %.2f 1234500 -> 1234500.00 %.2f 1234560 -> 1234560.00 @@ -62,7 +62,7 @@ %#.0f 0 -> 0. %#.1f 0 -> 0.0 %#.0f 1.5 -> 2. --- %#.0f 2.5 -> 2. See issue 6198. +%#.0f 2.5 -> 2. %#.0f 10.1 -> 10. %#.0f 1234.56 -> 1235. %#.1f 1.4 -> 1.4 @@ -108,18 +108,18 @@ %.0e 123456000 -> 1e+08 %.0e 0.5 -> 5e-01 %.0e 1.4 -> 1e+00 ---%.0e 1.5 -> 2e+00 See issue 6198. +%.0e 1.5 -> 2e+00 %.0e 1.6 -> 2e+00 %.0e 2.4999999 -> 2e+00 ---%.0e 2.5 -> 2e+00 See issue 6198. +%.0e 2.5 -> 2e+00 %.0e 2.5000001 -> 3e+00 %.0e 3.499999999999 -> 3e+00 %.0e 3.5 -> 4e+00 ---%.0e 4.5 -> 4e+00 See issue 6198. +%.0e 4.5 -> 4e+00 %.0e 5.5 -> 6e+00 ---%.0e 6.5 -> 6e+00 See issue 6198. +%.0e 6.5 -> 6e+00 %.0e 7.5 -> 8e+00 ---%.0e 8.5 -> 8e+00 See issue 6198. +%.0e 8.5 -> 8e+00 %.0e 9.4999 -> 9e+00 %.0e 9.5 -> 1e+01 %.0e 10.5 -> 1e+01 @@ -185,15 +185,15 @@ %#.0e 1.5 -> 2.e+00 %#.0e 1.6 -> 2.e+00 %#.0e 2.4999999 -> 2.e+00 ---%#.0e 2.5 -> 2.e+00 See issue 6198. +%#.0e 2.5 -> 2.e+00 %#.0e 2.5000001 -> 3.e+00 %#.0e 3.499999999999 -> 3.e+00 %#.0e 3.5 -> 4.e+00 ---%#.0e 4.5 -> 4.e+00 See issue 6198. +%#.0e 4.5 -> 4.e+00 %#.0e 5.5 -> 6.e+00 ---%#.0e 6.5 -> 6.e+00 See issue 6198. +%#.0e 6.5 -> 6.e+00 %#.0e 7.5 -> 8.e+00 ---%#.0e 8.5 -> 8.e+00 See issue 6198. +%#.0e 8.5 -> 8.e+00 %#.0e 9.4999 -> 9.e+00 %#.0e 9.5 -> 1.e+01 %#.0e 10.5 -> 1.e+01 @@ -281,11 +281,11 @@ -- alternate g formatting: always include decimal point and -- exactly significant digits. ---%#.0g 0 -> 0. See issue 6198. ---%#.1g 0 -> 0. See issue 6198. ---%#.2g 0 -> 0.0 See issue 6198. ---%#.3g 0 -> 0.00 See issue 6198. ---%#.4g 0 -> 0.000 See issue 6198. +%#.0g 0 -> 0. +%#.1g 0 -> 0. +%#.2g 0 -> 0.0 +%#.3g 0 -> 0.00 +%#.4g 0 -> 0.000 %#.0g 0.2 -> 0.2 %#.1g 0.2 -> 0.2 From python-checkins at python.org Tue Nov 24 16:12:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 15:12:55 -0000 Subject: [Python-checkins] r76496 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 16:12:55 2009 New Revision: 76496 Log: Blocked revisions 76495 via svnmerge ........ r76495 | mark.dickinson | 2009-11-24 15:12:20 +0000 (Tue, 24 Nov 2009) | 2 lines Issue #7117: Update float formatting testcases to match those in py3k. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Nov 24 16:13:28 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 15:13:28 -0000 Subject: [Python-checkins] r76497 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Tue Nov 24 16:13:27 2009 New Revision: 76497 Log: Blocked revisions 76495 via svnmerge ........ r76495 | mark.dickinson | 2009-11-24 15:12:20 +0000 (Tue, 24 Nov 2009) | 2 lines Issue #7117: Update float formatting testcases to match those in py3k. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 24 16:53:25 2009 From: python-checkins at python.org (vinay.sajip) Date: Tue, 24 Nov 2009 15:53:25 -0000 Subject: [Python-checkins] r76498 - python/trunk/Lib/logging/__init__.py Message-ID: Author: vinay.sajip Date: Tue Nov 24 16:53:25 2009 New Revision: 76498 Log: Made logging classes new-style and added name property to handlers. Modified: python/trunk/Lib/logging/__init__.py Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Tue Nov 24 16:53:25 2009 @@ -46,8 +46,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.0.9" -__date__ = "09 October 2009" +__version__ = "0.5.1.0" +__date__ = "24 November 2009" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -196,9 +196,9 @@ # #_lock is used to serialize access to shared data structures in this module. -#This needs to be an RLock because fileConfig() creates Handlers and so -#might arbitrary user threads. Since Handler.__init__() updates the shared -#dictionary _handlers, it needs to acquire the lock. But if configuring, +#This needs to be an RLock because fileConfig() creates and configures +#Handlers, and so might arbitrary user threads. Since Handler code updates the +#shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # @@ -227,7 +227,7 @@ # The logging record #--------------------------------------------------------------------------- -class LogRecord: +class LogRecord(object): """ A LogRecord instance represents an event being logged. @@ -335,7 +335,7 @@ # Formatter classes and functions #--------------------------------------------------------------------------- -class Formatter: +class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. @@ -467,7 +467,7 @@ # _defaultFormatter = Formatter() -class BufferingFormatter: +class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ @@ -509,7 +509,7 @@ # Filter classes and functions #--------------------------------------------------------------------------- -class Filter: +class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. @@ -546,7 +546,7 @@ return 0 return (record.name[self.nlen] == ".") -class Filterer: +class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. @@ -590,7 +590,7 @@ # Handler classes and functions #--------------------------------------------------------------------------- -_handlers = {} #repository of handlers (for flushing when shutdown called) +_handlers = {} #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized class Handler(Filterer): @@ -608,17 +608,33 @@ and the filter list to empty. """ Filterer.__init__(self) + self._name = None self.level = _checkLevel(level) self.formatter = None #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... - _handlers[self] = 1 _handlerList.insert(0, self) finally: _releaseLock() self.createLock() + def get_name(self): + return self._name + + def set_name(self, name): + _acquireLock() + try: + if self._name in _handlers: + del _handlers[self._name] + self._name = name + if name: + _handlers[name] = self + finally: + _releaseLock() + + name = property(get_name, set_name) + def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. @@ -716,7 +732,8 @@ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... - del _handlers[self] + if self._name and self._name in _handlers: + del _handlers[self._name] _handlerList.remove(self) finally: _releaseLock() @@ -869,7 +886,7 @@ # Manager classes and functions #--------------------------------------------------------------------------- -class PlaceHolder: +class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is @@ -916,7 +933,7 @@ return _loggerClass -class Manager: +class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. @@ -1269,7 +1286,7 @@ _loggerClass = Logger -class LoggerAdapter: +class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. From python-checkins at python.org Tue Nov 24 18:53:23 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Tue, 24 Nov 2009 17:53:23 -0000 Subject: [Python-checkins] r76499 - in python/trunk: Lib/test/pickletester.py Modules/cPickle.c Message-ID: Author: alexandre.vassalotti Date: Tue Nov 24 18:53:23 2009 New Revision: 76499 Log: Issue 7128: Removed reference to the non-existent copyreg module. The reference to copyreg was a unnoticed leftover from the compatibility support for the grand renaming of the standard library in Python 3. The compatibility support was reverted in r63493, but not completely as this patch shows. Based on a patch by Amaury Forgeot d'Arc. Modified: python/trunk/Lib/test/pickletester.py python/trunk/Modules/cPickle.c Modified: python/trunk/Lib/test/pickletester.py ============================================================================== --- python/trunk/Lib/test/pickletester.py (original) +++ python/trunk/Lib/test/pickletester.py Tue Nov 24 18:53:23 2009 @@ -1091,6 +1091,16 @@ s = StringIO.StringIO("X''.") self.assertRaises(EOFError, self.module.load, s) + def test_restricted(self): + # issue7128: cPickle failed in restricted mode + builtins = {self.module.__name__: self.module, + '__import__': __import__} + d = {} + teststr = "def f(): {0}.dumps(0)".format(self.module.__name__) + exec teststr in {'__builtins__': builtins}, d + d['f']() + + class AbstractPersistentPicklerTests(unittest.TestCase): # This class defines persistent_id() and persistent_load() Modified: python/trunk/Modules/cPickle.c ============================================================================== --- python/trunk/Modules/cPickle.c (original) +++ python/trunk/Modules/cPickle.c Tue Nov 24 18:53:23 2009 @@ -132,7 +132,7 @@ *__reduce_ex___str, *write_str, *append_str, *read_str, *readline_str, *__main___str, - *copyreg_str, *dispatch_table_str; + *dispatch_table_str; /************************************************************************* Internal Data type for pickle data. */ @@ -3069,7 +3069,7 @@ if (PyEval_GetRestricted()) { /* Restricted execution, get private tables */ - PyObject *m = PyImport_Import(copyreg_str); + PyObject *m = PyImport_ImportModule("copy_reg"); if (m == NULL) goto err; @@ -5852,7 +5852,6 @@ INIT_STR(append); INIT_STR(read); INIT_STR(readline); - INIT_STR(copyreg); INIT_STR(dispatch_table); if (!( copyreg = PyImport_ImportModule("copy_reg"))) From python-checkins at python.org Tue Nov 24 19:06:51 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Tue, 24 Nov 2009 18:06:51 -0000 Subject: [Python-checkins] r76500 - in python/branches/release26-maint: Lib/test/pickletester.py Modules/cPickle.c Message-ID: Author: alexandre.vassalotti Date: Tue Nov 24 19:06:51 2009 New Revision: 76500 Log: Merged revisions 76499 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76499 | alexandre.vassalotti | 2009-11-24 12:53:23 -0500 (Tue, 24 Nov 2009) | 9 lines Issue 7128: Removed reference to the non-existent copyreg module. The reference to copyreg was a unnoticed leftover from the compatibility support for the grand renaming of the standard library in Python 3. The compatibility support was reverted in r63493, but not completely as this patch shows. Based on a patch by Amaury Forgeot d'Arc. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/pickletester.py python/branches/release26-maint/Modules/cPickle.c Modified: python/branches/release26-maint/Lib/test/pickletester.py ============================================================================== --- python/branches/release26-maint/Lib/test/pickletester.py (original) +++ python/branches/release26-maint/Lib/test/pickletester.py Tue Nov 24 19:06:51 2009 @@ -1020,6 +1020,16 @@ s = StringIO.StringIO("X''.") self.assertRaises(EOFError, self.module.load, s) + def test_restricted(self): + # issue7128: cPickle failed in restricted mode + builtins = {self.module.__name__: self.module, + '__import__': __import__} + d = {} + teststr = "def f(): {0}.dumps(0)".format(self.module.__name__) + exec teststr in {'__builtins__': builtins}, d + d['f']() + + class AbstractPersistentPicklerTests(unittest.TestCase): # This class defines persistent_id() and persistent_load() Modified: python/branches/release26-maint/Modules/cPickle.c ============================================================================== --- python/branches/release26-maint/Modules/cPickle.c (original) +++ python/branches/release26-maint/Modules/cPickle.c Tue Nov 24 19:06:51 2009 @@ -132,7 +132,7 @@ *__reduce_ex___str, *write_str, *append_str, *read_str, *readline_str, *__main___str, - *copyreg_str, *dispatch_table_str; + *dispatch_table_str; /************************************************************************* Internal Data type for pickle data. */ @@ -2985,7 +2985,7 @@ if (PyEval_GetRestricted()) { /* Restricted execution, get private tables */ - PyObject *m = PyImport_Import(copyreg_str); + PyObject *m = PyImport_ImportModule("copy_reg"); if (m == NULL) goto err; @@ -5733,7 +5733,6 @@ INIT_STR(append); INIT_STR(read); INIT_STR(readline); - INIT_STR(copyreg); INIT_STR(dispatch_table); if (!( copyreg = PyImport_ImportModule("copy_reg"))) From python-checkins at python.org Tue Nov 24 19:10:33 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Tue, 24 Nov 2009 18:10:33 -0000 Subject: [Python-checkins] r76501 - python/branches/py3k Message-ID: Author: alexandre.vassalotti Date: Tue Nov 24 19:10:33 2009 New Revision: 76501 Log: Blocked revisions 76499 via svnmerge ........ r76499 | alexandre.vassalotti | 2009-11-24 12:53:23 -0500 (Tue, 24 Nov 2009) | 9 lines Issue 7128: Removed reference to the non-existent copyreg module. The reference to copyreg was a unnoticed leftover from the compatibility support for the grand renaming of the standard library in Python 3. The compatibility support was reverted in r63493, but not completely as this patch shows. Based on a patch by Amaury Forgeot d'Arc. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Nov 24 21:51:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 20:51:48 -0000 Subject: [Python-checkins] r76502 - in python/trunk/Modules/_io: _iomodule.h bufferedio.c Message-ID: Author: mark.dickinson Date: Tue Nov 24 21:51:48 2009 New Revision: 76502 Log: Issue #7228: Fix format mismatch when printing something of type off_t. (Should silence some compiler warnings.) Modified: python/trunk/Modules/_io/_iomodule.h python/trunk/Modules/_io/bufferedio.c Modified: python/trunk/Modules/_io/_iomodule.h ============================================================================== --- python/trunk/Modules/_io/_iomodule.h (original) +++ python/trunk/Modules/_io/_iomodule.h Tue Nov 24 21:51:48 2009 @@ -75,6 +75,14 @@ * Offset type for positioning. */ +/* Printing a variable of type off_t (with e.g., PyString_FromFormat) + correctly and without producing compiler warnings is surprisingly painful. + We identify an integer type whose size matches off_t and then: (1) cast the + off_t to that integer type and (2) use the appropriate conversion + specification. The cast is necessary: gcc complains about formatting a + long with "%lld" even when both long and long long have the same + precision. */ + #if defined(MS_WIN64) || defined(MS_WINDOWS) /* Windows uses long long for offsets */ @@ -83,6 +91,8 @@ # define PyLong_FromOff_t PyLong_FromLongLong # define PY_OFF_T_MAX PY_LLONG_MAX # define PY_OFF_T_MIN PY_LLONG_MIN +# define PY_OFF_T_COMPAT PY_LONG_LONG /* type compatible with off_t */ +# define PY_PRIdOFF "lld" /* format to use for that type */ #else @@ -93,16 +103,22 @@ # define PyLong_FromOff_t PyLong_FromSsize_t # define PY_OFF_T_MAX PY_SSIZE_T_MAX # define PY_OFF_T_MIN PY_SSIZE_T_MIN -#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) +# define PY_OFF_T_COMPAT Py_ssize_t +# define PY_PRIdOFF "zd" +#elif (HAVE_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG) # define PyLong_AsOff_t PyLong_AsLongLong # define PyLong_FromOff_t PyLong_FromLongLong # define PY_OFF_T_MAX PY_LLONG_MAX # define PY_OFF_T_MIN PY_LLONG_MIN +# define PY_OFF_T_COMPAT PY_LONG_LONG +# define PY_PRIdOFF "lld" #elif (SIZEOF_OFF_T == SIZEOF_LONG) # define PyLong_AsOff_t PyLong_AsLong # define PyLong_FromOff_t PyLong_FromLong # define PY_OFF_T_MAX LONG_MAX # define PY_OFF_T_MIN LONG_MIN +# define PY_OFF_T_COMPAT long +# define PY_PRIdOFF "ld" #else # error off_t does not match either size_t, long, or long long! #endif Modified: python/trunk/Modules/_io/bufferedio.c ============================================================================== --- python/trunk/Modules/_io/bufferedio.c (original) +++ python/trunk/Modules/_io/bufferedio.c Tue Nov 24 21:51:48 2009 @@ -582,7 +582,8 @@ if (n < 0) { if (!PyErr_Occurred()) PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); + "Raw stream returned invalid position %" PY_PRIdOFF, + (PY_OFF_T_COMPAT)n); return -1; } self->abs_pos = n; @@ -614,7 +615,8 @@ if (n < 0) { if (!PyErr_Occurred()) PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); + "Raw stream returned invalid position %" PY_PRIdOFF, + (PY_OFF_T_COMPAT)n); return -1; } self->abs_pos = n; From python-checkins at python.org Tue Nov 24 21:54:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 20:54:11 -0000 Subject: [Python-checkins] r76503 - in python/branches/py3k: Modules/_io/_iomodule.h Modules/_io/bufferedio.c Message-ID: Author: mark.dickinson Date: Tue Nov 24 21:54:11 2009 New Revision: 76503 Log: Merged revisions 76502 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76502 | mark.dickinson | 2009-11-24 20:51:48 +0000 (Tue, 24 Nov 2009) | 3 lines Issue #7228: Fix format mismatch when printing something of type off_t. (Should silence some compiler warnings.) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_io/_iomodule.h python/branches/py3k/Modules/_io/bufferedio.c Modified: python/branches/py3k/Modules/_io/_iomodule.h ============================================================================== --- python/branches/py3k/Modules/_io/_iomodule.h (original) +++ python/branches/py3k/Modules/_io/_iomodule.h Tue Nov 24 21:54:11 2009 @@ -70,6 +70,14 @@ * Offset type for positioning. */ +/* Printing a variable of type off_t (with e.g., PyString_FromFormat) + correctly and without producing compiler warnings is surprisingly painful. + We identify an integer type whose size matches off_t and then: (1) cast the + off_t to that integer type and (2) use the appropriate conversion + specification. The cast is necessary: gcc complains about formatting a + long with "%lld" even when both long and long long have the same + precision. */ + #if defined(MS_WIN64) || defined(MS_WINDOWS) /* Windows uses long long for offsets */ @@ -78,6 +86,8 @@ # define PyLong_FromOff_t PyLong_FromLongLong # define PY_OFF_T_MAX PY_LLONG_MAX # define PY_OFF_T_MIN PY_LLONG_MIN +# define PY_OFF_T_COMPAT PY_LONG_LONG /* type compatible with off_t */ +# define PY_PRIdOFF "lld" /* format to use for that type */ #else @@ -88,16 +98,22 @@ # define PyLong_FromOff_t PyLong_FromSsize_t # define PY_OFF_T_MAX PY_SSIZE_T_MAX # define PY_OFF_T_MIN PY_SSIZE_T_MIN -#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) +# define PY_OFF_T_COMPAT Py_ssize_t +# define PY_PRIdOFF "zd" +#elif (HAVE_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG) # define PyLong_AsOff_t PyLong_AsLongLong # define PyLong_FromOff_t PyLong_FromLongLong # define PY_OFF_T_MAX PY_LLONG_MAX # define PY_OFF_T_MIN PY_LLONG_MIN +# define PY_OFF_T_COMPAT PY_LONG_LONG +# define PY_PRIdOFF "lld" #elif (SIZEOF_OFF_T == SIZEOF_LONG) # define PyLong_AsOff_t PyLong_AsLong # define PyLong_FromOff_t PyLong_FromLong # define PY_OFF_T_MAX LONG_MAX # define PY_OFF_T_MIN LONG_MIN +# define PY_OFF_T_COMPAT long +# define PY_PRIdOFF "ld" #else # error off_t does not match either size_t, long, or long long! #endif Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Tue Nov 24 21:54:11 2009 @@ -582,7 +582,8 @@ if (n < 0) { if (!PyErr_Occurred()) PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); + "Raw stream returned invalid position %" PY_PRIdOFF, + (PY_OFF_T_COMPAT)n); return -1; } self->abs_pos = n; @@ -614,7 +615,8 @@ if (n < 0) { if (!PyErr_Occurred()) PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); + "Raw stream returned invalid position %" PY_PRIdOFF, + (PY_OFF_T_COMPAT)n); return -1; } self->abs_pos = n; From python-checkins at python.org Tue Nov 24 21:55:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 20:55:18 -0000 Subject: [Python-checkins] r76504 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 21:55:17 2009 New Revision: 76504 Log: Blocked revisions 76502 via svnmerge ........ r76502 | mark.dickinson | 2009-11-24 20:51:48 +0000 (Tue, 24 Nov 2009) | 3 lines Issue #7228: Fix format mismatch when printing something of type off_t. (Should silence some compiler warnings.) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Nov 24 21:56:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 24 Nov 2009 20:56:11 -0000 Subject: [Python-checkins] r76505 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Tue Nov 24 21:56:11 2009 New Revision: 76505 Log: Blocked revisions 76503 via svnmerge ................ r76503 | mark.dickinson | 2009-11-24 20:54:11 +0000 (Tue, 24 Nov 2009) | 10 lines Merged revisions 76502 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76502 | mark.dickinson | 2009-11-24 20:51:48 +0000 (Tue, 24 Nov 2009) | 3 lines Issue #7228: Fix format mismatch when printing something of type off_t. (Should silence some compiler warnings.) ........ ................ Modified: python/branches/release31-maint/ (props changed) From nnorwitz at gmail.com Tue Nov 24 22:44:35 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 24 Nov 2009 16:44:35 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091124214435.GA31720@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881029 refs] From solipsis at pitrou.net Wed Nov 25 00:47:25 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 25 Nov 2009 00:47:25 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76503): sum=14 Message-ID: <20091124234725.240F617715@ns6635.ovh.net> py3k results for svn r76503 (hg cset 43d4879ead14) -------------------------------------------------- test_urllib leaked [6, 4, 4] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogzkSP6h', '-x', 'test_httpservers'] From nnorwitz at gmail.com Wed Nov 25 00:54:04 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 24 Nov 2009 18:54:04 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091124235404.GA6464@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_zipimport_support leaked [25, 0, 0] references, sum=25 Less important issues: ---------------------- test_cmd_line leaked [0, 0, -25] references, sum=-25 test_popen2 leaked [-25, 0, 0] references, sum=-25 From python-checkins at python.org Wed Nov 25 01:34:31 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 00:34:31 -0000 Subject: [Python-checkins] r76506 - in sandbox/trunk/2to3/lib2to3/fixes: fix_imports.py fix_next.py fix_renames.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 01:34:31 2009 New Revision: 76506 Log: use generator expressions in any() Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_imports.py sandbox/trunk/2to3/lib2to3/fixes/fix_next.py sandbox/trunk/2to3/lib2to3/fixes/fix_renames.py Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_imports.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_imports.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_imports.py Wed Nov 25 01:34:31 2009 @@ -108,7 +108,7 @@ # Module usage could be in the trailer of an attribute lookup, so we # might have nested matches when "bare_with_attr" is present. if "bare_with_attr" not in results and \ - any([match(obj) for obj in attr_chain(node, "parent")]): + any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_next.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_next.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_next.py Wed Nov 25 01:34:31 2009 @@ -99,4 +99,4 @@ def is_subtree(root, node): if root == node: return True - return any([is_subtree(c, node) for c in root.children]) + return any(is_subtree(c, node) for c in root.children) Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_renames.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_renames.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_renames.py Wed Nov 25 01:34:31 2009 @@ -49,7 +49,7 @@ match = super(FixRenames, self).match results = match(node) if results: - if any([match(obj) for obj in attr_chain(node, "parent")]): + if any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False From python-checkins at python.org Wed Nov 25 10:03:31 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 09:03:31 -0000 Subject: [Python-checkins] r76507 - in python/trunk: Lib/logging/__init__.py Misc/NEWS Message-ID: Author: vinay.sajip Date: Wed Nov 25 10:03:30 2009 New Revision: 76507 Log: Issue #6615: logging: Used weak references in internal handler list. Modified: python/trunk/Lib/logging/__init__.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Wed Nov 25 10:03:30 2009 @@ -23,7 +23,7 @@ To use, simply 'import logging' and log away! """ -import sys, os, time, cStringIO, traceback, warnings +import sys, os, time, cStringIO, traceback, warnings, weakref __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', @@ -46,8 +46,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.1.0" -__date__ = "24 November 2009" +__version__ = "0.5.1.1" +__date__ = "25 November 2009" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -593,6 +593,27 @@ _handlers = {} #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized +def _removeHandlerRef(wr): + """ + Remove a handler reference from the internal cleanup list. + """ + _acquireLock() + try: + if wr in _handlerList: + _handlerList.remove(wr) + finally: + _releaseLock() + +def _addHandlerRef(handler): + """ + Add a handler to the internal cleanup list using a weak reference. + """ + _acquireLock() + try: + _handlerList.insert(0, weakref.ref(handler, _removeHandlerRef)) + finally: + _releaseLock() + class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. @@ -611,12 +632,8 @@ self._name = None self.level = _checkLevel(level) self.formatter = None - #get the module data lock, as we're updating a shared structure. - _acquireLock() - try: #unlikely to raise an exception, but you never know... - _handlerList.insert(0, self) - finally: - _releaseLock() + # Add the handler to the global _handlerList (for cleanup on shutdown) + _addHandlerRef(self) self.createLock() def get_name(self): @@ -724,8 +741,8 @@ """ Tidy up any resources used by the handler. - This version does removes the handler from an internal list - of handlers which is closed when shutdown() is called. Subclasses + This version removes the handler from an internal map of handlers, + _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ @@ -734,7 +751,6 @@ try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] - _handlerList.remove(self) finally: _releaseLock() @@ -1532,10 +1548,11 @@ Should be called at application exit. """ - for h in handlerList[:]: + for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: + h = wr() h.flush() h.close() except: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 25 10:03:30 2009 @@ -483,12 +483,14 @@ Library ------- +- Issue #6615: logging: Used weakrefs in internal handler list. + - Issue #1488943: difflib.Differ() doesn't always add hints for tab characters - Issue #6123: tarfile now opens empty archives correctly and consistently raises ReadError on empty files. -- Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can +- Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can be 2. - Issue #5037: Proxy the __unicode__ special method instead to __unicode__ @@ -563,7 +565,7 @@ - Issue #7071: byte-compilation in Distutils is now done with respect to sys.dont_write_bytecode. -- Issue #7066: archive_util.make_archive now restores the cwd if an error is +- Issue #7066: archive_util.make_archive now restores the cwd if an error is raised. Initial patch by Ezio Melotti. - Issue #6218: io.StringIO and io.BytesIO instances are now picklable with From python-checkins at python.org Wed Nov 25 10:14:07 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 09:14:07 -0000 Subject: [Python-checkins] r76507 - svn:log Message-ID: Author: vinay.sajip Revision: 76507 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Issue #6615: logging: Used weak references in internal handler list. \ No newline at end of file +Issue #6615: logging: Used weak references in internal handler list. Thanks to flox for the patch. \ No newline at end of file From python-checkins at python.org Wed Nov 25 10:22:48 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 09:22:48 -0000 Subject: [Python-checkins] r76508 - python/trunk/Lib/logging/__init__.py Message-ID: Author: vinay.sajip Date: Wed Nov 25 10:22:47 2009 New Revision: 76508 Log: logging: made _handlers a WeakValueDictionary. Modified: python/trunk/Lib/logging/__init__.py Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Wed Nov 25 10:22:47 2009 @@ -590,7 +590,7 @@ # Handler classes and functions #--------------------------------------------------------------------------- -_handlers = {} #map of handler names to handlers +_handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): From nnorwitz at gmail.com Wed Nov 25 10:27:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 25 Nov 2009 04:27:45 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091125092745.GA15868@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881032 refs] From python-checkins at python.org Wed Nov 25 10:53:56 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 09:53:56 -0000 Subject: [Python-checkins] r76507 - svn:log Message-ID: Author: vinay.sajip Revision: 76507 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Issue #6615: logging: Used weak references in internal handler list. Thanks to flox for the patch. \ No newline at end of file +Issue #6615: logging: Used weak references in internal handler list. Thanks to flox (Florent Xicluna) for the patch. \ No newline at end of file From nnorwitz at gmail.com Wed Nov 25 12:14:19 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 25 Nov 2009 06:14:19 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091125111419.GA2656@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [-84, 0, 0] references, sum=-84 Less important issues: ---------------------- test_zipimport_support leaked [-25, 25, 0] references, sum=0 From ncoghlan at gmail.com Wed Nov 25 12:28:13 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Wed, 25 Nov 2009 21:28:13 +1000 Subject: [Python-checkins] r76487 - python/trunk/Lib/test/test_multiprocessing.py In-Reply-To: <4b0beb02.1967f10a.20a6.ffff9ea0SMTPIN_ADDED@mx.google.com> References: <4b0beb02.1967f10a.20a6.ffff9ea0SMTPIN_ADDED@mx.google.com> Message-ID: <4B0D14CD.3010701@gmail.com> jesse.noller wrote: > Author: jesse.noller > Date: Tue Nov 24 15:17:29 2009 > New Revision: 76487 > > Log: > comment out test added in r76438, which caused refleaks You've probably already seen the Roundup traffic for this, but with Vinay's latest changes to the logging module you should be right to put this back in. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From python-checkins at python.org Wed Nov 25 15:12:04 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 14:12:04 -0000 Subject: [Python-checkins] r76509 - python/trunk/Lib/logging/__init__.py Message-ID: Author: vinay.sajip Date: Wed Nov 25 15:12:03 2009 New Revision: 76509 Log: logging: Issue 6615: Changed handler prepend to append. Modified: python/trunk/Lib/logging/__init__.py Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Wed Nov 25 15:12:03 2009 @@ -610,7 +610,7 @@ """ _acquireLock() try: - _handlerList.insert(0, weakref.ref(handler, _removeHandlerRef)) + _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() From python-checkins at python.org Wed Nov 25 18:12:57 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 17:12:57 -0000 Subject: [Python-checkins] r76513 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Wed Nov 25 18:12:57 2009 New Revision: 76513 Log: Blocked revisions 74962,75017,75131,75143,75147,75281,75423-75424,75482,75586,75929,76025,76050-76051,76126,76129,76132,76194,76212,76382,76392,76431,76434 via svnmerge ................ r74962 | ronald.oussoren | 2009-09-20 05:31:22 -0500 (Sun, 20 Sep 2009) | 2 lines Fix for issue 6851: urllib.urlopen crashes in a thread on OSX 10.6 ................ r75017 | ronald.oussoren | 2009-09-22 09:24:57 -0500 (Tue, 22 Sep 2009) | 4 lines The 'Navigation Toolbox' is not available at all for 64-bit code, make this explicit in the C code to avoid confusing error messages during the build. ................ r75131 | ronald.oussoren | 2009-09-29 08:00:44 -0500 (Tue, 29 Sep 2009) | 8 lines * Update the Mac/README file. Add the list of OSX-specific configure options to that README file with some explanation. * Be more strict in the configure script: complain loudly when the user has specified invalid combinations of OSX-specific configure arguments. The error message refers to the Mac/README file for more information. ................ r75143 | philip.jenvey | 2009-09-29 14:10:15 -0500 (Tue, 29 Sep 2009) | 5 lines #5329: fix os.popen* regression from 2.5: don't execute commands as a sequence through the shell. also document the correct subprocess replacement for this case patch from Jean-Paul Calderone and Jani Hakala ................ r75147 | ronald.oussoren | 2009-09-29 14:34:13 -0500 (Tue, 29 Sep 2009) | 4 lines Fix for issue6957: ensure that the OSX installer installs a version of Python that can build extensions on OSX 10.6. ................ r75281 | ronald.oussoren | 2009-10-08 03:04:15 -0500 (Thu, 08 Oct 2009) | 3 lines Ensure that _scproxy gets build even when --disable-toolbox-glue is specified on OSX. Fixes a regression in 2.6.3. ................ r75423 | neil.schemenauer | 2009-10-14 14:23:53 -0500 (Wed, 14 Oct 2009) | 2 lines Add support to the ihooks module for relative imports. ................ r75424 | neil.schemenauer | 2009-10-14 14:33:31 -0500 (Wed, 14 Oct 2009) | 4 lines Make cPickle.Unpickler.noload() handle dict subclasses. noload() is an obscure, undocumentated feature so no test was added. Closes issue #1101399. ................ r75482 | ronald.oussoren | 2009-10-18 02:07:00 -0500 (Sun, 18 Oct 2009) | 3 lines Fix for issue 7149: a regression in 2.6.3 that causes an exception when trying to detect proxy settings on OSX. ................ r75586 | vinay.sajip | 2009-10-21 15:22:14 -0500 (Wed, 21 Oct 2009) | 1 line Issue #7077: logging: SysLogHandler now treats Unicode as per RFC 5424. ................ r75929 | vinay.sajip | 2009-10-28 18:28:16 -0500 (Wed, 28 Oct 2009) | 1 line Issue 7199: Documentation made slightly more consistent w.r.t. logging level enumeration. ................ r76025 | raymond.hettinger | 2009-11-01 14:45:16 -0600 (Sun, 01 Nov 2009) | 1 line Fix exception handling in itertools.izip_longest(). ................ r76050 | gregory.p.smith | 2009-11-01 19:37:37 -0600 (Sun, 01 Nov 2009) | 5 lines see http://bugs.python.org/issue1006238 this merges in the following patch to make cross compilation of the chflags check easier: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-lang/python/files/python-2.6-chflags-cross.patch?rev=1.1 ................ r76051 | gregory.p.smith | 2009-11-01 19:38:35 -0600 (Sun, 01 Nov 2009) | 2 lines build using r76050 ................ r76126 | benjamin.peterson | 2009-11-05 15:29:56 -0600 (Thu, 05 Nov 2009) | 9 lines Merged revisions 76125 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76125 | benjamin.peterson | 2009-11-05 15:26:55 -0600 (Thu, 05 Nov 2009) | 1 line handle newline issues better for comparing files ........ ................ r76129 | benjamin.peterson | 2009-11-05 17:20:06 -0600 (Thu, 05 Nov 2009) | 13 lines Merged revisions 76127-76128 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76127 | benjamin.peterson | 2009-11-05 17:04:58 -0600 (Thu, 05 Nov 2009) | 1 line set svn:eol-style ........ r76128 | benjamin.peterson | 2009-11-05 17:07:46 -0600 (Thu, 05 Nov 2009) | 1 line skip this test on windows to avoid newline horrors ........ ................ r76132 | benjamin.peterson | 2009-11-05 17:54:42 -0600 (Thu, 05 Nov 2009) | 9 lines Merged revisions 76131 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76131 | benjamin.peterson | 2009-11-05 17:53:21 -0600 (Thu, 05 Nov 2009) | 1 line import sys ........ ................ r76194 | raymond.hettinger | 2009-11-10 13:35:55 -0600 (Tue, 10 Nov 2009) | 3 lines Show example of how to make a sorted dictionary ................ r76212 | senthil.kumaran | 2009-11-11 11:22:35 -0600 (Wed, 11 Nov 2009) | 3 lines Fixing the NameError on Windows - issue1235 ................ r76382 | raymond.hettinger | 2009-11-18 14:28:22 -0600 (Wed, 18 Nov 2009) | 1 line Issue 7263: Fix set.intersection() docstring. ................ r76392 | raymond.hettinger | 2009-11-18 19:22:04 -0600 (Wed, 18 Nov 2009) | 1 line Fix docstrings for itertools combinatoric functions. ................ r76431 | mark.dickinson | 2009-11-20 13:27:43 -0600 (Fri, 20 Nov 2009) | 1 line Regenerate configure with GNU autoconf 2.61. ................ r76434 | jesse.noller | 2009-11-21 08:06:24 -0600 (Sat, 21 Nov 2009) | 1 line revert unintended change to multiprocessing/queues.py ................ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Nov 25 18:19:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 17:19:56 -0000 Subject: [Python-checkins] r76514 - in python/branches/py3k: Lib/logging/__init__.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 18:19:56 2009 New Revision: 76514 Log: Merged revisions 76498,76507-76509 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76498 | vinay.sajip | 2009-11-24 09:53:25 -0600 (Tue, 24 Nov 2009) | 1 line Made logging classes new-style and added name property to handlers. ........ r76507 | vinay.sajip | 2009-11-25 03:03:30 -0600 (Wed, 25 Nov 2009) | 1 line Issue #6615: logging: Used weak references in internal handler list. Thanks to flox (Florent Xicluna) for the patch. ........ r76508 | vinay.sajip | 2009-11-25 03:22:47 -0600 (Wed, 25 Nov 2009) | 1 line logging: made _handlers a WeakValueDictionary. ........ r76509 | vinay.sajip | 2009-11-25 08:12:03 -0600 (Wed, 25 Nov 2009) | 1 line logging: Issue 6615: Changed handler prepend to append. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/logging/__init__.py Modified: python/branches/py3k/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k/Lib/logging/__init__.py (original) +++ python/branches/py3k/Lib/logging/__init__.py Wed Nov 25 18:19:56 2009 @@ -23,7 +23,7 @@ To use, simply 'import logging' and log away! """ -import sys, os, time, io, traceback, warnings +import sys, os, time, io, traceback, warnings, weakref __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', @@ -46,8 +46,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.0.9" -__date__ = "09 October 2009" +__version__ = "0.5.1.1" +__date__ = "25 November 2009" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -193,9 +193,9 @@ # #_lock is used to serialize access to shared data structures in this module. -#This needs to be an RLock because fileConfig() creates Handlers and so -#might arbitrary user threads. Since Handler.__init__() updates the shared -#dictionary _handlers, it needs to acquire the lock. But if configuring, +#This needs to be an RLock because fileConfig() creates and configures +#Handlers, and so might arbitrary user threads. Since Handler code updates the +#shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # @@ -224,7 +224,7 @@ # The logging record #--------------------------------------------------------------------------- -class LogRecord: +class LogRecord(object): """ A LogRecord instance represents an event being logged. @@ -332,7 +332,7 @@ # Formatter classes and functions #--------------------------------------------------------------------------- -class Formatter: +class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. @@ -464,7 +464,7 @@ # _defaultFormatter = Formatter() -class BufferingFormatter: +class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ @@ -506,7 +506,7 @@ # Filter classes and functions #--------------------------------------------------------------------------- -class Filter: +class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. @@ -543,7 +543,7 @@ return 0 return (record.name[self.nlen] == ".") -class Filterer: +class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. @@ -587,9 +587,30 @@ # Handler classes and functions #--------------------------------------------------------------------------- -_handlers = {} #repository of handlers (for flushing when shutdown called) +_handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized +def _removeHandlerRef(wr): + """ + Remove a handler reference from the internal cleanup list. + """ + _acquireLock() + try: + if wr in _handlerList: + _handlerList.remove(wr) + finally: + _releaseLock() + +def _addHandlerRef(handler): + """ + Add a handler to the internal cleanup list using a weak reference. + """ + _acquireLock() + try: + _handlerList.append(weakref.ref(handler, _removeHandlerRef)) + finally: + _releaseLock() + class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. @@ -605,16 +626,28 @@ and the filter list to empty. """ Filterer.__init__(self) + self._name = None self.level = _checkLevel(level) self.formatter = None - #get the module data lock, as we're updating a shared structure. + # Add the handler to the global _handlerList (for cleanup on shutdown) + _addHandlerRef(self) + self.createLock() + + def get_name(self): + return self._name + + def set_name(self, name): _acquireLock() - try: #unlikely to raise an exception, but you never know... - _handlers[self] = 1 - _handlerList.insert(0, self) + try: + if self._name in _handlers: + del _handlers[self._name] + self._name = name + if name: + _handlers[name] = self finally: _releaseLock() - self.createLock() + + name = property(get_name, set_name) def createLock(self): """ @@ -705,16 +738,16 @@ """ Tidy up any resources used by the handler. - This version does removes the handler from an internal list - of handlers which is closed when shutdown() is called. Subclasses + This version removes the handler from an internal map of handlers, + _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... - del _handlers[self] - _handlerList.remove(self) + if self._name and self._name in _handlers: + del _handlers[self._name] finally: _releaseLock() @@ -866,7 +899,7 @@ # Manager classes and functions #--------------------------------------------------------------------------- -class PlaceHolder: +class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is @@ -913,7 +946,7 @@ return _loggerClass -class Manager: +class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. @@ -1266,7 +1299,7 @@ _loggerClass = Logger -class LoggerAdapter: +class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. @@ -1512,10 +1545,11 @@ Should be called at application exit. """ - for h in handlerList[:]: + for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: + h = wr() h.flush() h.close() except: From python-checkins at python.org Wed Nov 25 18:46:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 17:46:27 -0000 Subject: [Python-checkins] r76515 - in python/branches/py3k: Demo/scripts/wh.py Doc/faq/gui.rst Doc/whatsnew/2.7.rst Lib/code.py Lib/mailbox.py Lib/os.py Lib/runpy.py Lib/test/test_grammar.py Lib/test/test_runpy.py Objects/listobject.c Python/compile.c Tools/pybench/pybench.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 18:46:26 2009 New Revision: 76515 Log: Merged revisions 75264,75268,75293,75318,75391-75392,75436,75478,75971,76003,76058,76140-76141,76231,76380,76428-76429 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75264 | andrew.kuchling | 2009-10-05 17:30:22 -0500 (Mon, 05 Oct 2009) | 1 line Add various items ........ r75268 | andrew.kuchling | 2009-10-05 17:45:39 -0500 (Mon, 05 Oct 2009) | 1 line Remove two notes ........ r75293 | kristjan.jonsson | 2009-10-09 09:32:19 -0500 (Fri, 09 Oct 2009) | 2 lines http://bugs.python.org/issue7029 a non-default timer wasn't actually used by the individual Tests. ........ r75318 | benjamin.peterson | 2009-10-10 16:15:58 -0500 (Sat, 10 Oct 2009) | 1 line remove script which uses long gone module ........ r75391 | andrew.kuchling | 2009-10-13 10:49:33 -0500 (Tue, 13 Oct 2009) | 1 line Link to PEP ........ r75392 | andrew.kuchling | 2009-10-13 11:11:49 -0500 (Tue, 13 Oct 2009) | 1 line Various link, textual, and markup fixes ........ r75436 | benjamin.peterson | 2009-10-15 10:39:15 -0500 (Thu, 15 Oct 2009) | 1 line don't need to mess up sys.path ........ r75478 | senthil.kumaran | 2009-10-17 20:58:45 -0500 (Sat, 17 Oct 2009) | 3 lines Fix a typo. ........ r75971 | benjamin.peterson | 2009-10-30 22:56:15 -0500 (Fri, 30 Oct 2009) | 1 line add some checks for evaluation order with parenthesis #7210 ........ r76003 | antoine.pitrou | 2009-10-31 19:30:13 -0500 (Sat, 31 Oct 2009) | 6 lines Hopefully fix the buildbot problems on test_mailbox, by computing the maildir toc cache refresh date before actually refreshing the cache. (see #6896) ........ r76058 | benjamin.peterson | 2009-11-02 10:14:19 -0600 (Mon, 02 Nov 2009) | 1 line grant list.index() a more informative error message #7252 ........ r76140 | nick.coghlan | 2009-11-07 02:13:55 -0600 (Sat, 07 Nov 2009) | 1 line Add test for runpy.run_module package execution and use something other than logging as the example of a non-executable package ........ r76141 | nick.coghlan | 2009-11-07 02:15:01 -0600 (Sat, 07 Nov 2009) | 1 line Some minor cleanups to private runpy code and docstrings ........ r76231 | benjamin.peterson | 2009-11-12 17:42:23 -0600 (Thu, 12 Nov 2009) | 1 line this main is much more useful ........ r76380 | antoine.pitrou | 2009-11-18 14:20:46 -0600 (Wed, 18 Nov 2009) | 3 lines Mention Giampolo R's new FTP TLS support in the what's new file ........ r76428 | benjamin.peterson | 2009-11-19 20:15:50 -0600 (Thu, 19 Nov 2009) | 1 line turn goto into do while loop ........ r76429 | benjamin.peterson | 2009-11-19 20:56:43 -0600 (Thu, 19 Nov 2009) | 2 lines avoid doing an uneeded import in a function ........ Removed: python/branches/py3k/Demo/scripts/wh.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/faq/gui.rst python/branches/py3k/Doc/whatsnew/2.7.rst python/branches/py3k/Lib/code.py python/branches/py3k/Lib/mailbox.py python/branches/py3k/Lib/os.py python/branches/py3k/Lib/runpy.py python/branches/py3k/Lib/test/test_grammar.py python/branches/py3k/Lib/test/test_runpy.py python/branches/py3k/Objects/listobject.c python/branches/py3k/Python/compile.c python/branches/py3k/Tools/pybench/pybench.py Deleted: python/branches/py3k/Demo/scripts/wh.py ============================================================================== --- python/branches/py3k/Demo/scripts/wh.py Wed Nov 25 18:46:26 2009 +++ (empty file) @@ -1,2 +0,0 @@ -# This is here so I can use 'wh' instead of 'which' in '~/bin/generic_python' -import which Modified: python/branches/py3k/Doc/faq/gui.rst ============================================================================== --- python/branches/py3k/Doc/faq/gui.rst (original) +++ python/branches/py3k/Doc/faq/gui.rst Wed Nov 25 18:46:26 2009 @@ -25,27 +25,26 @@ page at http://www.tcl.tk. Tcl/Tk is fully portable to the MacOS, Windows, and Unix platforms. -wxWindows +wxWidgets ''''''''' -wxWindows is a portable GUI class library written in C++ that's a portable -interface to various platform-specific libraries; wxWidgets is a Python -interface to wxWindows. wxWindows supports Windows and MacOS; on Unix variants, -it supports both GTk+ and Motif toolkits. wxWindows preserves the look and feel -of the underlying graphics toolkit, and there is quite a rich widget set and -collection of GDI classes. See `the wxWindows page `_ -for more details. - -`wxWidgets `_ is an extension module that wraps many of -the wxWindows C++ classes, and is quickly gaining popularity amongst Python -developers. You can get wxWidgets as part of the source or CVS distribution of -wxWindows, or directly from its home page. +wxWidgets is a GUI class library written in C++ that's a portable +interface to various platform-specific libraries, and that has a +Python interface called `wxPython `__. + +wxWidgets preserves the look and feel of the +underlying graphics toolkit, and has a large set of widgets and +collection of GDI classes. See `the wxWidgets page +`_ for more details. + +wxWidgets supports Windows and MacOS; on Unix variants, +it supports both GTk+ and Motif toolkits. Qt ''' There are bindings available for the Qt toolkit (`PyQt -`_) and for KDE (PyKDE). If +`_) and for KDE (`PyKDE `__). If you're writing open source software, you don't need to pay for PyQt, but if you want to write proprietary applications, you must buy a PyQt license from `Riverbank Computing `_ and (up to Qt 4.4; @@ -56,7 +55,7 @@ '''' PyGtk bindings for the `Gtk+ toolkit `_ have been -implemented by by James Henstridge; see ftp://ftp.gtk.org/pub/gtk/python/. +implemented by James Henstridge; see . FLTK '''' @@ -85,14 +84,15 @@ `The Mac port `_ by Jack Jansen has a rich and ever-growing set of modules that support the native Mac toolbox calls. The port -includes support for MacOS9 and MacOS X's Carbon libraries. By installing the -`PyObjc Objective-C bridge `_, Python programs -can use MacOS X's Cocoa libraries. See the documentation that comes with the Mac -port. +supports MacOS X's Carbon libraries. + +By installing the `PyObjc Objective-C bridge +`_, Python programs can use MacOS X's +Cocoa libraries. See the documentation that comes with the Mac port. :ref:`Pythonwin ` by Mark Hammond includes an interface to the -Microsoft Foundation Classes and a Python programming environment using it -that's written mostly in Python. +Microsoft Foundation Classes and a Python programming environment +that's written mostly in Python using the MFC classes. Tkinter questions @@ -105,23 +105,26 @@ applications, the applications will not be truly stand-alone, as the application will still need the Tcl and Tk libraries. -One solution is to ship the application with the tcl and tk libraries, and point +One solution is to ship the application with the Tcl and Tk libraries, and point to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY` environment variables. To get truly stand-alone applications, the Tcl scripts that form the library have to be integrated into the application as well. One tool supporting that is SAM (stand-alone modules), which is part of the Tix distribution -(http://tix.mne.com). Build Tix with SAM enabled, perform the appropriate call -to Tclsam_init etc inside Python's Modules/tkappinit.c, and link with libtclsam -and libtksam (you might include the Tix libraries as well). +(http://tix.sourceforge.net/). + +Build Tix with SAM enabled, perform the appropriate call to +:cfunc:`Tclsam_init`, etc. inside Python's +:file:`Modules/tkappinit.c`, and link with libtclsam and libtksam (you +might include the Tix libraries as well). Can I have Tk events handled while waiting for I/O? --------------------------------------------------- Yes, and you don't even need threads! But you'll have to restructure your I/O -code a bit. Tk has the equivalent of Xt's XtAddInput() call, which allows you +code a bit. Tk has the equivalent of Xt's :cfunc:`XtAddInput()` call, which allows you to register a callback function which will be called from the Tk mainloop when I/O is possible on a file descriptor. Here's what you need:: Modified: python/branches/py3k/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.7.rst Wed Nov 25 18:46:26 2009 @@ -49,46 +49,195 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.7. -No release schedule has been decided yet for 2.7. +This article explains the new features in Python 2.7. No release +schedule has been decided yet for 2.7; the schedule will eventually be +described in :pep:`373`. .. Compare with previous release in 2 - 3 sentences here. add hyperlink when the documentation becomes available online. -Python 3.1 -================ +.. _whatsnew27-python31: -Much as Python 2.6 incorporated features from Python 3.0, -version 2.7 is influenced by features from 3.1. +Python 3.1 Features +======================= -XXX mention importlib; anything else? +Much as Python 2.6 incorporated features from Python 3.0, +version 2.7 incorporates some of the new features +in Python 3.1. The 2.x series continues to provide tools +for migrating to the 3.x series. + +A partial list of 3.1 features that were backported to 2.7: + +* A version of the :mod:`io` library, rewritten in C for performance. +* The ordered-dictionary type described in :ref:`pep-0372`. +* The new format specified described in :ref:`pep-0378`. +* The :class:`memoryview` object. +* A small subset of the :mod:`importlib` module `described below <#importlib-section>`__. One porting change: the :option:`-3` switch now automatically enables the :option:`-Qwarn` switch that causes warnings about using classic division with integers and long integers. +Other new Python3-mode warnings include: + +* :func:`operator.isCallable` and :func:`operator.sequenceIncludes`, + which are not supported in 3.x. + .. ======================================================================== .. Large, PEP-level features and changes should be described here. .. ======================================================================== +.. _pep-0372: + PEP 372: Adding an ordered dictionary to collections ==================================================== -XXX write this +Regular Python dictionaries iterate over key/value pairs in arbitrary order. +Over the years, a number of authors have written alternative implementations +that remember the order that the keys were originally inserted. Based on +the experiences from those implementations, a new +:class:`collections.OrderedDict` class has been introduced. + +The :class:`OrderedDict` API is substantially the same as regular dictionaries +but will iterate over keys and values in a guaranteed order depending on +when a key was first inserted:: + + >>> from collections import OrderedDict + >>> d = OrderedDict([('first', 1), ('second', 2), + ... ('third', 3)]) + >>> d.items() + [('first', 1), ('second', 2), ('third', 3)] + +If a new entry overwrites an existing entry, the original insertion +position is left unchanged:: + + >>> d['second'] = 4 + >>> d.items() + [('first', 1), ('second', 4), ('third', 3)] + +Deleting an entry and reinserting it will move it to the end:: + + >>> del d['second'] + >>> d['second'] = 5 + >>> d.items() + [('first', 1), ('third', 3), ('second', 5)] + +The :meth:`popitem` method has an optional *last* argument +that defaults to True. If *last* is True, the most recently +added key is returned and removed; if it's False, the +oldest key is selected:: + + >>> od = OrderedDict([(x,0) for x in range(20)]) + >>> od.popitem() + (19, 0) + >>> od.popitem() + (18, 0) + >>> od.popitem(False) + (0, 0) + >>> od.popitem(False) + (1, 0) + +Comparing two ordered dictionaries checks both the keys and values, +and requires that the insertion order was the same:: + + >>> od1 = OrderedDict([('first', 1), ('second', 2), + ... ('third', 3)]) + >>> od2 = OrderedDict([('third', 3), ('first', 1), + ... ('second', 2)]) + >>> od1==od2 + False + >>> # Move 'third' key to the end + >>> del od2['third'] ; od2['third'] = 3 + >>> od1==od2 + True + +Comparing an :class:`OrderedDict` with a regular dictionary +ignores the insertion order and just compares the keys and values. + +How does the :class:`OrderedDict` work? It maintains a doubly-linked +list of keys, appending new keys to the list as they're inserted. A +secondary dictionary maps keys to their corresponding list node, so +deletion doesn't have to traverse the entire linked list and therefore +remains O(1). + +.. XXX check O(1)-ness with Raymond + +The standard library now supports use of ordered dictionaries in several +modules. The :mod:`configparser` module uses them by default. This lets +configuration files be read, modified, and then written back in their original +order. The *_asdict()* method for :func:`collections.namedtuple` now +returns an ordered dictionary with the values appearing in the same order as +the underlying tuple indicies. The :mod:`json` module is being built-out with +an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. +Support was also added for third-party tools like `PyYAML `_. + +.. seealso:: + + :pep:`372` - Adding an ordered dictionary to collections + PEP written by Armin Ronacher and Raymond Hettinger; + implemented by Raymond Hettinger. -Several modules will now use :class:`OrderedDict` by default. The -:mod:`ConfigParser` module uses :class:`OrderedDict` for the list -of sections and the options within a section. -The :meth:`namedtuple._asdict` method returns an :class:`OrderedDict` -as well. +.. _pep-0378: + +PEP 378: Format Specifier for Thousands Separator +==================================================== +To make program output more readable, it can be useful to add +separators to large numbers and render them as +18,446,744,073,709,551,616 instead of 18446744073709551616. + +The fully general solution for doing this is the :mod:`locale` module, +which can use different separators ("," in North America, "." in +Europe) and different grouping sizes, but :mod:`locale` is complicated +to use and unsuitable for multi-threaded applications where different +threads are producing output for different locales. + +Therefore, a simple comma-grouping mechanism has been added to the +mini-language used by the string :meth:`format` method. When +formatting a floating-point number, simply include a comma between the +width and the precision:: + + >>> '{:20,.2}'.format(f) + '18,446,744,073,709,551,616.00' + +This mechanism is not adaptable at all; commas are always used as the +separator and the grouping is always into three-digit groups. The +comma-formatting mechanism isn't as general as the :mod:`locale` +module, but it's easier to use. + +.. XXX "Format String Syntax" in string.rst could use many more examples. + +.. seealso:: + + :pep:`378` - Format Specifier for Thousands Separator + PEP written by Raymond Hettinger; implemented by Eric Smith. Other Language Changes ====================== Some smaller changes made to the core Python language are: -* :meth:`str.format` method now supports automatic numbering of the replacement +* The :keyword:`with` statement can now use multiple context managers + in one statement. Context managers are processed from left to right + and each one is treated as beginning a new :keyword:`with` statement. + This means that:: + + with A() as a, B() as b: + ... suite of statements ... + + is equivalent to:: + + with A() as a: + with B() as b: + ... suite of statements ... + + The :func:`contextlib.nested` function provides a very similar + function, so it's no longer necessary and has been deprecated. + + (Proposed in http://codereview.appspot.com/53094; implemented by + Georg Brandl.) + +* The :meth:`str.format` method now supports automatic numbering of the replacement fields. This makes using :meth:`str.format` more closely resemble using ``%s`` formatting:: @@ -102,7 +251,13 @@ specifier will use the next argument, and so on. You can't mix auto-numbering and explicit numbering -- either number all of your specifier fields or none of them -- but you can mix auto-numbering and named fields, as in the second - example above. (Contributed by Eric Smith; :issue`5237`.) + example above. (Contributed by Eric Smith; :issue:`5237`.) + + Complex numbers now correctly support usage with :func:`format`. + Specifying a precision or comma-separation applies to both the real + and imaginary parts of the number, but a specified field width and + alignment is applied to the whole of the resulting ``1.5+3j`` + output. (Contributed by Eric Smith; :issue:`1588`.) * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent @@ -125,7 +280,7 @@ point now round differently, returning the floating-point number closest to the number. This doesn't matter for small integers that can be converted exactly, but for large numbers that will - unavoidably lose precision, Python 2.7 will now approximate more + unavoidably lose precision, Python 2.7 now approximates more closely. For example, Python 2.6 computed the following:: >>> n = 295147905179352891391 @@ -146,10 +301,20 @@ (Implemented by Mark Dickinson; :issue:`3166`.) -* The :class:`bytearray` type's :meth:`translate` method will - now accept ``None`` as its first argument. (Fixed by Georg Brandl; +* The :class:`bytearray` type's :meth:`translate` method now accepts + ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) +* When using ``@classmethod`` and ``@staticmethod`` to wrap + methods as class or static methods, the wrapper object now + exposes the wrapped function as their :attr:`__func__` attribute. + (Contributed by Amaury Forgeot d'Arc, after a suggestion by + George Sakkis; :issue:`5982`.) + +* A new encoding named "cp720", used primarily for Arabic text, is now + supported. (Contributed by Alexander Belchenko and Amaury Forgeot + d'Arc; :issue:`1616979`.) + .. ====================================================================== @@ -164,6 +329,10 @@ and benchmark. The new mechanism is only supported on certain compilers, such as gcc, SunPro, and icc. +* A new opcode was added to perform the initial setup for + :keyword:`with` statements, looking up the :meth:`__enter__` and + :meth:`__exit__` methods. (Contributed by Benjamin Peterson.) + * The garbage collector now performs better when many objects are being allocated without deallocating any. A full garbage collection pass is only performed when the middle generation has been collected @@ -184,7 +353,7 @@ considered and traversed by the collector. (Contributed by Antoine Pitrou; :issue:`4688`.) -* Integers are now stored internally either in base 2**15 or in base +* Long integers are now stored internally either in base 2**15 or in base 2**30, the base being determined at build time. Previously, they were always stored in base 2**15. Using base 2**30 gives significant performance improvements on 64-bit machines, but @@ -227,6 +396,21 @@ faster bytecode. (Patch by Antoine Pitrou, back-ported to 2.7 by Jeffrey Yasskin; :issue:`4715`.) +* The :mod:`pickle` and :mod:`cPickle` modules now automatically + intern the strings used for attribute names, reducing memory usage + of the objects resulting from unpickling. (Contributed by Jake + McGuire; :issue:`5084`.) + +* The :mod:`cPickle` module now special-cases dictionaries, + nearly halving the time required to pickle them. + (Contributed by Collin Winter; :issue:`5670`.) + +* Converting an integer or long integer to a decimal string was made + faster by special-casing base 10 instead of using a generalized + conversion function that supports arbitrary bases. + (Patch by Gawain Bolton; :issue:`6713`.) + + .. ====================================================================== New and Improved Modules @@ -238,6 +422,14 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. +* The :mod:`bdb` module's base debugging class :class:`Bdb` + gained a feature for skipping modules. The constructor + now takes an iterable containing glob-style patterns such as + ``django.*``; the debugger will not step into stack frames + from a module that matches one of these patterns. + (Contributed by Maru Newby after a suggestion by + Senthil Kumaran; :issue:`5142`.) + * The :mod:`bz2` module's :class:`BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) @@ -279,6 +471,9 @@ Contributed by Raymond Hettinger; :issue:`1696199`. + The new `OrderedDict` class is described in the earlier section + :ref:`pep-0372`. + The :class:`namedtuple` class now has an optional *rename* parameter. If *rename* is true, field names that are invalid because they've been repeated or that aren't legal Python identifiers will be @@ -295,10 +490,42 @@ The :class:`deque` data type now exposes its maximum length as the read-only :attr:`maxlen` attribute. (Added by Raymond Hettinger.) -* In Distutils, :func:`distutils.sdist.add_defaults` now uses +* The :mod:`ctypes` module now always converts ``None`` to a C NULL + pointer for arguments declared as pointers. (Changed by Thomas + Heller; :issue:`4606`.) + +* New method: the :class:`Decimal` class gained a + :meth:`from_float` class method that performs an exact conversion + of a floating-point number to a :class:`Decimal`. + Note that this is an **exact** conversion that strives for the + closest decimal approximation to the floating-point representation's value; + the resulting decimal value will therefore still include the inaccuracy, + if any. + For example, ``Decimal.from_float(0.1)`` returns + ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. + (Implemented by Raymond Hettinger; :issue:`4796`.) + + The constructor for :class:`Decimal` now accepts non-European + Unicode characters, such as Arabic-Indic digits. (Contributed by + Mark Dickinson; :issue:`6595`.) + + When using :class:`Decimal` instances with a string's + :meth:`format` method, the default alignment was previously + left-alignment. This has been changed to right-alignment, which seems + more sensible for numeric types. (Changed by Mark Dickinson; :issue:`6857`.) + +* Distutils is being more actively developed, thanks to Tarek Ziade + has taken over maintenance of the package. A new + :file:`setup.py` subcommand, ``check``, will + check that the arguments being passed to the :func:`setup` function + are complete and correct (:issue:`5732`). + + :func:`distutils.sdist.add_defaults` now uses *package_dir* and *data_files* to create the MANIFEST file. - :mod:`distutils.sysconfig` will now read the :envvar:`AR` - environment variable. + :mod:`distutils.sysconfig` now reads the :envvar:`AR` and + :envvar:`ARFLAGS` environment variables. + + .. ARFLAGS done in #5941 It is no longer mandatory to store clear-text passwords in the :file:`.pypirc` file when registering and uploading packages to PyPI. As long @@ -312,18 +539,7 @@ process, but instead simply not install the failing extension. (Contributed by Georg Brandl; :issue:`5583`.) -* New method: the :class:`Decimal` class gained a - :meth:`from_float` class method that performs an exact conversion - of a floating-point number to a :class:`Decimal`. - Note that this is an **exact** conversion that strives for the - closest decimal approximation to the floating-point representation's value; - the resulting decimal value will therefore still include the inaccuracy, - if any. - For example, ``Decimal.from_float(0.1)`` returns - ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. - (Implemented by Raymond Hettinger; :issue:`4796`.) - -* The :class:`Fraction` class will now accept two rational numbers +* The :class:`Fraction` class now accepts two rational numbers as arguments to its constructor. (Implemented by Mark Dickinson; :issue:`5812`.) @@ -338,7 +554,32 @@ recorded in a gzipped file by providing an optional timestamp to the constructor. (Contributed by Jacques Frechet; :issue:`4272`.) -* The :class:`io.FileIO` class now raises an :exc:`OSError` when passed +* The :mod:`hashlib` module was inconsistent about accepting + input as a Unicode object or an object that doesn't support + the buffer protocol. The behavior was different depending on + whether :mod:`hashlib` was using an external OpenSSL library + or its built-in implementations. Python 2.7 makes the + behavior consistent, always rejecting such objects by raising a + :exc:`TypeError`. (Fixed by Gregory P. Smith; :issue:`3745`.) + +* The default :class:`HTTPResponse` class used by the :mod:`httplib` module now + supports buffering, resulting in much faster reading of HTTP responses. + (Contributed by Kristjan Valur Jonsson; :issue:`4879`.) + +* The :mod:`imaplib` module now supports IPv6 addresses. + (Contributed by Derek Morr; :issue:`1655`.) + +* The :mod:`io` library has been upgraded to the version shipped with + Python 3.1. For 3.1, the I/O library was entirely rewritten in C + and is 2 to 20 times faster depending on the task at hand. The + original Python version was renamed to the :mod:`_pyio` module. + + One minor resulting change: the :class:`io.TextIOBase` class now + has an :attr:`errors` attribute giving the error setting + used for encoding and decoding errors (one of ``'strict'``, ``'replace'``, + ``'ignore'``). + + The :class:`io.FileIO` class now raises an :exc:`OSError` when passed an invalid file descriptor. (Implemented by Benjamin Peterson; :issue:`4991`.) @@ -382,12 +623,19 @@ with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) +* New functions: the :mod:`math` module now has + a :func:`gamma` function. + (Contributed by Mark Dickinson and nirinA raseliarison; :issue:`3366`.) + * The :mod:`multiprocessing` module's :class:`Manager*` classes can now be passed a callable that will be called whenever a subprocess is started, along with a set of arguments that will be passed to the callable. (Contributed by lekma; :issue:`5585`.) +* The :mod:`nntplib` module now supports IPv6 addresses. + (Contributed by Derek Morr; :issue:`1664`.) + * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) @@ -396,6 +644,36 @@ now accept an optional *flags* argument, for consistency with the other functions in the module. (Added by Gregory P. Smith.) +* The :mod:`shutil` module's :func:`copyfile` and :func:`copytree` + functions now raises a :exc:`SpecialFileError` exception when + asked to copy a named pipe. Previously the code would treat + named pipes like a regular file by opening them for reading, and + this would block indefinitely. (Fixed by Antoine Pitrou; :issue:`3002`.) + +* New functions: in the :mod:`site` module, three new functions + return various site- and user-specific paths. + :func:`getsitepackages` returns a list containing all + global site-packages directories, and + :func:`getusersitepackages` returns the path of the user's + site-packages directory. + :func:`getuserbase` returns the value of the :envvar:``USER_BASE`` + environment variable, giving the path to a directory that can be used + to store data. + (Contributed by Tarek Ziade; :issue:`6693`.) + +* The :mod:`SocketServer` module's :class:`TCPServer` class now + has a :attr:`disable_nagle_algorithm` class attribute. + The default value is False; if overridden to be True, + new request connections will have the TCP_NODELAY option set to + prevent buffering many small sends into a single TCP packet. + (Contributed by Kristjan Valur Jonsson; :issue:`6192`.) + +* The :mod:`struct` module will no longer silently ignore overflow + errors when a value is too large for a particular integer format + code (one of ``bBhHiIlLqQ``); it now always raises a + :exc:`struct.error` exception. (Changed by Mark Dickinson; + :issue:`1523`.) + * New function: the :mod:`subprocess` module's :func:`check_output` runs a command with a specified set of arguments and returns the command's output as a string when the command runs without @@ -422,122 +700,151 @@ named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. (Contributed by Ross Light; :issue:`4285`.) +* The :mod:`tarfile` module now supports filtering the :class:`TarInfo` + objects being added to a tar file. When you call :meth:`TarFile.add`, + instance, you may supply an optional *filter* argument + that's a callable. The *filter* callable will be passed the + :class:`TarInfo` for every file being added, and can modify and return it. + If the callable returns ``None``, the file will be excluded from the + resulting archive. This is more powerful than the existing + *exclude* argument, which has therefore been deprecated. + (Added by Lars Gustaebel; :issue:`6856`.) + * The :mod:`threading` module's :meth:`Event.wait` method now returns the internal flag on exit. This means the method will usually return true because :meth:`wait` is supposed to block until the internal flag becomes true. The return value will only be false if a timeout was provided and the operation timed out. - (Contributed by XXX; :issue:`1674032`.) + (Contributed by Tim Lesher; :issue:`1674032`.) -* The :mod:`unittest` module was enhanced in several ways. - The progress messages will now show 'x' for expected failures - and 'u' for unexpected successes when run in verbose mode. - (Contributed by Benjamin Peterson.) - Test cases can raise the :exc:`SkipTest` exception to skip a test. - (:issue:`1034053`.) - - The error messages for :meth:`assertEqual`, - :meth:`assertTrue`, and :meth:`assertFalse` - failures now provide more information. If you set the - :attr:`longMessage` attribute of your :class:`TestCase` classes to - true, both the standard error message and any additional message you - provide will be printed for failures. (Added by Michael Foord; :issue:`5663`.) - - The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now - return a context handler when called without providing a callable - object to run. For example, you can write this:: - - with self.assertRaises(KeyError): - raise ValueError - - (Implemented by Antoine Pitrou; :issue:`4444`.) - - The methods :meth:`addCleanup` and :meth:`doCleanups` were added. - :meth:`addCleanup` allows you to add cleanup functions that - will be called unconditionally (after :meth:`setUp` if - :meth:`setUp` fails, otherwise after :meth:`tearDown`). This allows - for much simpler resource allocation and deallocation during tests. - :issue:`5679` - - A number of new methods were added that provide more specialized - tests. Many of these methods were written by Google engineers - for use in their test suites; Gregory P. Smith, Michael Foord, and - GvR worked on merging them into Python's version of :mod:`unittest`. - - * :meth:`assertIsNone` and :meth:`assertIsNotNone` take one - expression and verify that the result is or is not ``None``. - - * :meth:`assertIs` and :meth:`assertIsNot` take two values and check - whether the two values evaluate to the same object or not. - (Added by Michael Foord; :issue:`2578`.) - - * :meth:`assertGreater`, :meth:`assertGreaterEqual`, - :meth:`assertLess`, and :meth:`assertLessEqual` compare - two quantities. - - * :meth:`assertMultiLineEqual` compares two strings, and if they're - not equal, displays a helpful comparison that highlights the - differences in the two strings. - - * :meth:`assertRegexpMatches` checks whether its first argument is a - string matching a regular expression provided as its second argument. - - * :meth:`assertRaisesRegexp` checks whether a particular exception - is raised, and then also checks that the string representation of - the exception matches the provided regular expression. - - * :meth:`assertIn` and :meth:`assertNotIn` tests whether - *first* is or is not in *second*. - - * :meth:`assertSameElements` tests whether two provided sequences - contain the same elements. - - * :meth:`assertSetEqual` compares whether two sets are equal, and - only reports the differences between the sets in case of error. - - * Similarly, :meth:`assertListEqual` and :meth:`assertTupleEqual` - compare the specified types and explain the differences. - More generally, :meth:`assertSequenceEqual` compares two sequences - and can optionally check whether both sequences are of a - particular type. - - * :meth:`assertDictEqual` compares two dictionaries and reports the - differences. :meth:`assertDictContainsSubset` checks whether - all of the key/value pairs in *first* are found in *second*. - - * :meth:`assertAlmostEqual` and :meth:`assertNotAlmostEqual` short-circuit - (automatically pass or fail without checking decimal places) if the objects - are equal. - - * :meth:`loadTestsFromName` properly honors the ``suiteClass`` attribute of - the :class:`TestLoader`. (Fixed by Mark Roddy; :issue:`6866`.) - - * A new hook, :meth:`addTypeEqualityFunc` takes a type object and a - function. The :meth:`assertEqual` method will use the function - when both of the objects being compared are of the specified type. - This function should compare the two objects and raise an - exception if they don't match; it's a good idea for the function - to provide additional information about why the two objects are - matching, much as the new sequence comparison methods do. - - :func:`unittest.main` now takes an optional ``exit`` argument. - If False ``main`` doesn't call :func:`sys.exit` allowing it to - be used from the interactive interpreter. :issue:`3379`. - - :class:`TestResult` has new :meth:`startTestRun` and - :meth:`stopTestRun` methods; called immediately before - and after a test run. :issue:`5728` by Robert Collins. - -* The :func:`is_zipfile` function in the :mod:`zipfile` module will now - accept a file object, in addition to the path names accepted in earlier +* The :func:`is_zipfile` function in the :mod:`zipfile` module now + accepts a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) :mod:`zipfile` now supports archiving empty directories and extracts them correctly. (Fixed by Kuba Wieczorek; :issue:`4710`.) +* The :mod:`ftplib` module gains the ability to establish secure FTP + connections using TLS encapsulation of authentication as well as + subsequent control and data transfers. This is provided by the new + :class:`ftplib.FTP_TLS` class. + (Contributed by Giampaolo Rodola', :issue:`2054`.) + .. ====================================================================== .. whole new modules get described in subsections here +Unit Testing Enhancements +--------------------------------- + +The :mod:`unittest` module was enhanced in several ways. +The progress messages now shows 'x' for expected failures +and 'u' for unexpected successes when run in verbose mode. +(Contributed by Benjamin Peterson.) +Test cases can raise the :exc:`SkipTest` exception to skip a test. +(:issue:`1034053`.) + +.. XXX describe test discovery (Contributed by Michael Foord; :issue:`6001`.) + +The error messages for :meth:`assertEqual`, +:meth:`assertTrue`, and :meth:`assertFalse` +failures now provide more information. If you set the +:attr:`longMessage` attribute of your :class:`TestCase` classes to +true, both the standard error message and any additional message you +provide will be printed for failures. (Added by Michael Foord; :issue:`5663`.) + +The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now +return a context handler when called without providing a callable +object to run. For example, you can write this:: + + with self.assertRaises(KeyError): + raise ValueError + +(Implemented by Antoine Pitrou; :issue:`4444`.) + +The methods :meth:`addCleanup` and :meth:`doCleanups` were added. +:meth:`addCleanup` allows you to add cleanup functions that +will be called unconditionally (after :meth:`setUp` if +:meth:`setUp` fails, otherwise after :meth:`tearDown`). This allows +for much simpler resource allocation and deallocation during tests. +:issue:`5679` + +A number of new methods were added that provide more specialized +tests. Many of these methods were written by Google engineers +for use in their test suites; Gregory P. Smith, Michael Foord, and +GvR worked on merging them into Python's version of :mod:`unittest`. + +* :meth:`assertIsNone` and :meth:`assertIsNotNone` take one + expression and verify that the result is or is not ``None``. + +* :meth:`assertIs` and :meth:`assertIsNot` take two values and check + whether the two values evaluate to the same object or not. + (Added by Michael Foord; :issue:`2578`.) + +* :meth:`assertGreater`, :meth:`assertGreaterEqual`, + :meth:`assertLess`, and :meth:`assertLessEqual` compare + two quantities. + +* :meth:`assertMultiLineEqual` compares two strings, and if they're + not equal, displays a helpful comparison that highlights the + differences in the two strings. + +* :meth:`assertRegexpMatches` checks whether its first argument is a + string matching a regular expression provided as its second argument. + +* :meth:`assertRaisesRegexp` checks whether a particular exception + is raised, and then also checks that the string representation of + the exception matches the provided regular expression. + +* :meth:`assertIn` and :meth:`assertNotIn` tests whether + *first* is or is not in *second*. + +* :meth:`assertSameElements` tests whether two provided sequences + contain the same elements. + +* :meth:`assertSetEqual` compares whether two sets are equal, and + only reports the differences between the sets in case of error. + +* Similarly, :meth:`assertListEqual` and :meth:`assertTupleEqual` + compare the specified types and explain the differences. + More generally, :meth:`assertSequenceEqual` compares two sequences + and can optionally check whether both sequences are of a + particular type. + +* :meth:`assertDictEqual` compares two dictionaries and reports the + differences. :meth:`assertDictContainsSubset` checks whether + all of the key/value pairs in *first* are found in *second*. + +* :meth:`assertAlmostEqual` and :meth:`assertNotAlmostEqual` short-circuit + (automatically pass or fail without checking decimal places) if the objects + are equal. + +* :meth:`loadTestsFromName` properly honors the ``suiteClass`` attribute of + the :class:`TestLoader`. (Fixed by Mark Roddy; :issue:`6866`.) + +* A new hook, :meth:`addTypeEqualityFunc` takes a type object and a + function. The :meth:`assertEqual` method will use the function + when both of the objects being compared are of the specified type. + This function should compare the two objects and raise an + exception if they don't match; it's a good idea for the function + to provide additional information about why the two objects are + matching, much as the new sequence comparison methods do. + +:func:`unittest.main` now takes an optional ``exit`` argument. +If False ``main`` doesn't call :func:`sys.exit` allowing it to +be used from the interactive interpreter. :issue:`3379`. + +:class:`TestResult` has new :meth:`startTestRun` and +:meth:`stopTestRun` methods; called immediately before +and after a test run. :issue:`5728` by Robert Collins. + +With all these changes, the :file:`unittest.py` was becoming awkwardly +large, so the module was turned into a package and the code split into +several files (by Benjamin Peterson). This doesn't affect how the +module is imported. + + +.. _importlib-section: + importlib: Importing Modules ------------------------------ @@ -549,7 +856,7 @@ :mod:`importlib` package, but instead has a tiny subset that contains a single function, :func:`import_module`. -``import_module(*name*, *package*=None)`` imports a module. *name* is +``import_module(name, package=None)`` imports a module. *name* is a string containing the module or package's name. It's possible to do relative imports by providing a string that begins with a ``.`` character, such as ``..utils.errors``. For relative imports, the @@ -607,8 +914,8 @@ Changes to Python's build process and to the C API include: * If you use the :file:`.gdbinit` file provided with Python, - the "pyo" macro in the 2.7 version will now work when the thread being - debugged doesn't hold the GIL; the macro will now acquire it before printing. + the "pyo" macro in the 2.7 version now works correctly when the thread being + debugged doesn't hold the GIL; the macro now acquires it before printing. (Contributed by Victor Stinner; :issue:`3632`.) * :cfunc:`Py_AddPendingCall` is now thread-safe, letting any @@ -616,8 +923,57 @@ is particularly useful for asynchronous IO operations. (Contributed by Kristjan Valur Jonsson; :issue:`4293`.) +* New function: :cfunc:`PyCode_NewEmpty` creates an empty code object; + only the filename, function name, and first line number are required. + This is useful to extension modules that are attempting to + construct a more useful traceback stack. Previously such + extensions needed to call :cfunc:`PyCode_New`, which had many + more arguments. (Added by Jeffrey Yasskin.) + +* New function: :cfunc:`PyFrame_GetLineNumber` takes a frame object + and returns the line number that the frame is currently executing. + Previously code would need to get the index of the bytecode + instruction currently executing, and then look up the line number + corresponding to that address. (Added by Jeffrey Yasskin.) + +* New macros: the Python header files now define the following macros: + :cmacro:`Py_ISALNUM`, + :cmacro:`Py_ISALPHA`, + :cmacro:`Py_ISDIGIT`, + :cmacro:`Py_ISLOWER`, + :cmacro:`Py_ISSPACE`, + :cmacro:`Py_ISUPPER`, + :cmacro:`Py_ISXDIGIT`, + and :cmacro:`Py_TOLOWER`, :cmacro:`Py_TOUPPER`. + All of these functions are analogous to the C + standard macros for classifying characters, but ignore the current + locale setting, because in + several places Python needs to analyze characters in a + locale-independent way. (Added by Eric Smith; + :issue:`5793`.) + + .. XXX these macros don't seem to be described in the c-api docs. + +* The complicated interaction between threads and process forking has + been changed. Previously, the child process created by + :func:`os.fork` might fail because the child is created with only a + single thread running, the thread performing the :func:`os.fork`. + If other threads were holding a lock, such as Python's import lock, + when the fork was performed, the lock would still be marked as + "held" in the new process. But in the child process nothing would + ever release the lock, since the other threads weren't replicated, + and the child process would no longer be able to perform imports. + + Python 2.7 now acquires the import lock before performing an + :func:`os.fork`, and will also clean up any locks created using the + :mod:`threading` module. C extension modules that have internal + locks, or that call :cfunc:`fork()` themselves, will not benefit + from this clean-up. + + (Fixed by Thomas Wouters; :issue:`1590864`.) + * Global symbols defined by the :mod:`ctypes` module are now prefixed - with ``Py`, or with ``_ctypes``. (Implemented by Thomas + with ``Py``, or with ``_ctypes``. (Implemented by Thomas Heller; :issue:`3102`.) * The :program:`configure` script now checks for floating-point rounding bugs @@ -626,6 +982,12 @@ but it's available if anyone wishes to use it. (Added by Mark Dickinson; :issue:`2937`.) +* The build process now creates the necessary files for pkg-config + support. (Contributed by Clinton Roy; :issue:`3585`.) + +* The build process now supports Subversion 1.7. (Contributed by + Arfrever Frehtes Taifersar Arahesis; :issue:`6094`.) + .. ====================================================================== Port-Specific Changes: Windows @@ -642,12 +1004,15 @@ the native thread-local storage functions are now used. (Contributed by Kristjan Valur Jonsson; :issue:`3582`.) +* The :func:`os.listdir` function now correctly fails + for an empty path. (Fixed by Hirokazu Yamamoto; :issue:`5913`.) + .. ====================================================================== Port-Specific Changes: Mac OS X ----------------------------------- -* The ``/Library/Python/2.7/site-packages`` is now appended to +* The path ``/Library/Python/2.7/site-packages`` is now appended to ``sys.path``, in order to share added packages between the system installation and a user-installed copy of the same version. (Changed by Ronald Oussoren; :issue:`4865`.) @@ -666,12 +1031,12 @@ * The :file:`regrtest.py` script now takes a :option:`--randseed=` switch that takes an integer that will be used as the random seed for the :option:`-r` option that executes tests in random order. - The :option:`-r` option also now reports the seed that was used + The :option:`-r` option also reports the seed that was used (Added by Collin Winter.) * The :file:`regrtest.py` script now takes a :option:`-j` switch that takes an integer specifying how many tests run in parallel. This - allows to shorten the total runtime on multi-core machines. + allows reducing the total runtime on multi-core machines. This option is compatible with several other options, including the :option:`-R` switch which is known to produce long runtimes. (Added by Antoine Pitrou, :issue:`6152`.) @@ -684,6 +1049,17 @@ This section lists previously described changes and other bugfixes that may require changes to your code: +* When using :class:`Decimal` instances with a string's + :meth:`format` method, the default alignment was previously + left-alignment. This has been changed to right-alignment, which might + change the output of your programs. + (Changed by Mark Dickinson; :issue:`6857`.) + + Another :meth:`format`-related change: the default precision used + for floating-point and complex numbers was changed from 6 decimal + places to 12, which matches the precision used by :func:`str`. + (Changed by Eric Smith; :issue:`5920`.) + * Because of an optimization for the :keyword:`with` statement, the special methods :meth:`__enter__` and :meth:`__exit__` must belong to the object's type, and cannot be directly attached to the object's instance. This Modified: python/branches/py3k/Lib/code.py ============================================================================== --- python/branches/py3k/Lib/code.py (original) +++ python/branches/py3k/Lib/code.py Wed Nov 25 18:46:26 2009 @@ -287,6 +287,5 @@ console.interact(banner) -if __name__ == '__main__': - import pdb - pdb.run("interact()\n") +if __name__ == "__main__": + interact() Modified: python/branches/py3k/Lib/mailbox.py ============================================================================== --- python/branches/py3k/Lib/mailbox.py (original) +++ python/branches/py3k/Lib/mailbox.py Wed Nov 25 18:46:26 2009 @@ -469,12 +469,21 @@ def _refresh(self): """Update table of contents mapping.""" - new_mtime = os.path.getmtime(os.path.join(self._path, 'new')) - cur_mtime = os.path.getmtime(os.path.join(self._path, 'cur')) + if self._last_read is not None: + for subdir in ('new', 'cur'): + mtime = os.path.getmtime(os.path.join(self._path, subdir)) + if mtime > self._last_read: + break + else: + return - if (self._last_read is not None and - new_mtime <= self._last_read and cur_mtime <= self._last_read): - return + # We record the current time - 1sec so that, if _refresh() is called + # again in the same second, we will always re-read the mailbox + # just in case it's been modified. (os.path.mtime() only has + # 1sec resolution.) This results in a few unnecessary re-reads + # when _refresh() is called multiple times in the same second, + # but once the clock ticks over, we will only re-read as needed. + now = time.time() - 1 self._toc = {} def update_dir (subdir): @@ -489,14 +498,7 @@ update_dir('new') update_dir('cur') - # We record the current time - 1sec so that, if _refresh() is called - # again in the same second, we will always re-read the mailbox - # just in case it's been modified. (os.path.mtime() only has - # 1sec resolution.) This results in a few unnecessary re-reads - # when _refresh() is called multiple times in the same second, - # but once the clock ticks over, we will only re-read as needed. - now = int(time.time() - 1) - self._last_read = time.time() - 1 + self._last_read = now def _lookup(self, key): """Use TOC to return subpath for given key, or raise a KeyError.""" Modified: python/branches/py3k/Lib/os.py ============================================================================== --- python/branches/py3k/Lib/os.py (original) +++ python/branches/py3k/Lib/os.py Wed Nov 25 18:46:26 2009 @@ -249,7 +249,7 @@ dirs.remove('CVS') # don't visit CVS directories """ - from os.path import join, isdir, islink + islink, join, isdir = path.islink, path.join, path.isdir # We may not have read permission for top, in which case we can't # get a list of the files the directory contains. os.walk @@ -275,9 +275,9 @@ if topdown: yield top, dirs, nondirs for name in dirs: - path = join(top, name) - if followlinks or not islink(path): - for x in walk(path, topdown, onerror, followlinks): + new_path = join(top, name) + if followlinks or not islink(new_path): + for x in walk(new_path, topdown, onerror, followlinks): yield x if not topdown: yield top, dirs, nondirs Modified: python/branches/py3k/Lib/runpy.py ============================================================================== --- python/branches/py3k/Lib/runpy.py (original) +++ python/branches/py3k/Lib/runpy.py Wed Nov 25 18:46:26 2009 @@ -62,7 +62,7 @@ def _run_code(code, run_globals, init_globals=None, mod_name=None, mod_fname=None, mod_loader=None, pkg_name=None): - """Helper for _run_module_code""" + """Helper to run code in nominated namespace""" if init_globals is not None: run_globals.update(init_globals) run_globals.update(__name__ = mod_name, @@ -75,7 +75,7 @@ def _run_module_code(code, init_globals=None, mod_name=None, mod_fname=None, mod_loader=None, pkg_name=None): - """Helper for run_module""" + """Helper to run code in new namespace with sys modified""" with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname): mod_globals = temp_module.module.__dict__ _run_code(code, mod_globals, init_globals, @@ -103,7 +103,7 @@ raise ImportError("No module named %s" % mod_name) if loader.is_package(mod_name): if mod_name == "__main__" or mod_name.endswith(".__main__"): - raise ImportError(("Cannot use package as __main__ module")) + raise ImportError("Cannot use package as __main__ module") try: pkg_main_name = mod_name + ".__main__" return _get_module_details(pkg_main_name) @@ -116,29 +116,22 @@ filename = _get_filename(loader, mod_name) return mod_name, loader, code, filename - -def _get_main_module_details(): - # Helper that gives a nicer error message when attempting to - # execute a zipfile or directory by invoking __main__.py - main_name = "__main__" - try: - return _get_module_details(main_name) - except ImportError as exc: - if main_name in str(exc): - raise ImportError("can't find %r module in %r" % - (main_name, sys.path[0])) - raise - -# This function is the actual implementation of the -m switch and direct -# execution of zipfiles and directories and is deliberately kept private. -# This avoids a repeat of the situation where run_module() no longer met the -# needs of mainmodule.c, but couldn't be changed because it was public +# XXX ncoghlan: Should this be documented and made public? +# (Current thoughts: don't repeat the mistake that lead to its +# creation when run_module() no longer met the needs of +# mainmodule.c, but couldn't be changed because it was public) def _run_module_as_main(mod_name, alter_argv=True): """Runs the designated module in the __main__ namespace - These __*__ magic variables will be overwritten: + Note that the executed module will have full access to the + __main__ namespace. If this is not desirable, the run_module() + function sbould be used to run the module code in a fresh namespace. + + At the very least, these variables in __main__ will be overwritten: + __name__ __file__ __loader__ + __package__ """ try: if alter_argv or mod_name != "__main__": # i.e. -m switch @@ -146,7 +139,16 @@ else: # i.e. directory or zipfile execution mod_name, loader, code, fname = _get_main_module_details() except ImportError as exc: - msg = "%s: %s" % (sys.executable, str(exc)) + # Try to provide a good error message + # for directories, zip files and the -m switch + if alter_argv: + # For -m switch, just display the exception + info = str(exc) + else: + # For directories/zipfiles, let the user + # know what the code was looking for + info = "can't find '__main__.py' in %r" % sys.argv[0] + msg = "%s: %s" % (sys.executable, info) sys.exit(msg) pkg_name = mod_name.rpartition('.')[0] main_globals = sys.modules["__main__"].__dict__ @@ -173,6 +175,18 @@ return _run_code(code, {}, init_globals, run_name, fname, loader, pkg_name) +def _get_main_module_details(): + # Helper that gives a nicer error message when attempting to + # execute a zipfile or directory by invoking __main__.py + main_name = "__main__" + try: + return _get_module_details(main_name) + except ImportError as exc: + if main_name in str(exc): + raise ImportError("can't find %r module in %r" % + (main_name, sys.path[0])) + raise + # XXX (ncoghlan): Perhaps expose the C API function # as imp.get_importer instead of reimplementing it in Python? Modified: python/branches/py3k/Lib/test/test_grammar.py ============================================================================== --- python/branches/py3k/Lib/test/test_grammar.py (original) +++ python/branches/py3k/Lib/test/test_grammar.py Wed Nov 25 18:46:26 2009 @@ -915,6 +915,14 @@ self.assertEqual((6 / 2 if 1 else 3), 3) self.assertEqual((6 < 4 if 0 else 2), 2) + def test_paren_evaluation(self): + self.assertEqual(16 // (4 // 2), 8) + self.assertEqual((16 // 4) // 2, 2) + self.assertEqual(16 // 4 // 2, 2) + self.assertTrue(False is (2 is 3)) + self.assertFalse((False is 2) is 3) + self.assertFalse(False is 2 is 3) + def test_main(): run_unittest(TokenTests, GrammarTests) Modified: python/branches/py3k/Lib/test/test_runpy.py ============================================================================== --- python/branches/py3k/Lib/test/test_runpy.py (original) +++ python/branches/py3k/Lib/test/test_runpy.py Wed Nov 25 18:46:26 2009 @@ -100,8 +100,8 @@ self.expect_import_error("a.bee") self.expect_import_error(".howard") self.expect_import_error("..eaten") - # Package - self.expect_import_error("logging") + # Package without __main__.py + self.expect_import_error("multiprocessing") def test_library_module(self): run_module("runpy") @@ -113,9 +113,9 @@ pkg_file.close() return pkg_fname - def _make_pkg(self, source, depth): + def _make_pkg(self, source, depth, mod_base="runpy_test"): pkg_name = "__runpy_pkg__" - test_fname = "runpy_test.py" + test_fname = mod_base+os.extsep+"py" pkg_dir = sub_dir = tempfile.mkdtemp() if verbose: print(" Package tree in:", sub_dir) sys.path.insert(0, pkg_dir) @@ -130,7 +130,7 @@ mod_file.write(source) mod_file.close() if verbose: print(" Created:", mod_fname) - mod_name = (pkg_name+".")*depth + "runpy_test" + mod_name = (pkg_name+".")*depth + mod_base return pkg_dir, mod_fname, mod_name def _del_pkg(self, top, depth, mod_name): @@ -179,6 +179,28 @@ self._del_pkg(pkg_dir, depth, mod_name) if verbose: print("Module executed successfully") + def _check_package(self, depth): + pkg_dir, mod_fname, mod_name = ( + self._make_pkg("x=1\n", depth, "__main__")) + pkg_name, _, _ = mod_name.rpartition(".") + forget(mod_name) + try: + if verbose: print("Running from source:", pkg_name) + d1 = run_module(pkg_name) # Read from source + self.assertTrue("x" in d1) + self.assertTrue(d1["x"] == 1) + del d1 # Ensure __loader__ entry doesn't keep file open + __import__(mod_name) + os.remove(mod_fname) + if verbose: print("Running from compiled:", pkg_name) + d2 = run_module(pkg_name) # Read from bytecode + self.assertTrue("x" in d2) + self.assertTrue(d2["x"] == 1) + del d2 # Ensure __loader__ entry doesn't keep file open + finally: + self._del_pkg(pkg_dir, depth, pkg_name) + if verbose: print("Package executed successfully") + def _add_relative_modules(self, base_dir, source, depth): if depth <= 1: raise ValueError("Relative module test needs depth > 1") @@ -240,6 +262,11 @@ if verbose: print("Testing package depth:", depth) self._check_module(depth) + def test_run_package(self): + for depth in range(1, 4): + if verbose: print("Testing package depth:", depth) + self._check_package(depth) + def test_explicit_relative_import(self): for depth in range(2, 5): if verbose: print("Testing relative imports at depth:", depth) Modified: python/branches/py3k/Objects/listobject.c ============================================================================== --- python/branches/py3k/Objects/listobject.c (original) +++ python/branches/py3k/Objects/listobject.c Wed Nov 25 18:46:26 2009 @@ -2098,7 +2098,8 @@ listindex(PyListObject *self, PyObject *args) { Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v; + PyObject *v, *format_tuple, *err_string; + static PyObject *err_format = NULL; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, _PyEval_SliceIndex, &start, @@ -2121,7 +2122,20 @@ else if (cmp < 0) return NULL; } - PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list"); + if (err_format == NULL) { + err_format = PyUnicode_FromString("%r is not in list"); + if (err_format == NULL) + return NULL; + } + format_tuple = PyTuple_Pack(1, v); + if (format_tuple == NULL) + return NULL; + err_string = PyUnicode_Format(err_format, format_tuple); + Py_DECREF(format_tuple); + if (err_string == NULL) + return NULL; + PyErr_SetObject(PyExc_ValueError, err_string); + Py_DECREF(err_string); return NULL; } Modified: python/branches/py3k/Python/compile.c ============================================================================== --- python/branches/py3k/Python/compile.c (original) +++ python/branches/py3k/Python/compile.c Wed Nov 25 18:46:26 2009 @@ -3802,49 +3802,47 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) { basicblock *b; - int bsize, totsize, extended_arg_count, last_extended_arg_count = 0; + int bsize, totsize, extended_arg_count = 0, last_extended_arg_count; int i; /* Compute the size of each block and fixup jump args. Replace block pointer with position in bytecode. */ -start: - totsize = 0; - for (i = a->a_nblocks - 1; i >= 0; i--) { - b = a->a_postorder[i]; - bsize = blocksize(b); - b->b_offset = totsize; - totsize += bsize; - } - extended_arg_count = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - bsize = b->b_offset; - for (i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - /* Relative jumps are computed relative to - the instruction pointer after fetching - the jump instruction. - */ - bsize += instrsize(instr); - if (instr->i_jabs) - instr->i_oparg = instr->i_target->b_offset; - else if (instr->i_jrel) { - int delta = instr->i_target->b_offset - bsize; - instr->i_oparg = delta; + do { + totsize = 0; + for (i = a->a_nblocks - 1; i >= 0; i--) { + b = a->a_postorder[i]; + bsize = blocksize(b); + b->b_offset = totsize; + totsize += bsize; + } + last_extended_arg_count = extended_arg_count; + extended_arg_count = 0; + for (b = c->u->u_blocks; b != NULL; b = b->b_list) { + bsize = b->b_offset; + for (i = 0; i < b->b_iused; i++) { + struct instr *instr = &b->b_instr[i]; + /* Relative jumps are computed relative to + the instruction pointer after fetching + the jump instruction. + */ + bsize += instrsize(instr); + if (instr->i_jabs) + instr->i_oparg = instr->i_target->b_offset; + else if (instr->i_jrel) { + int delta = instr->i_target->b_offset - bsize; + instr->i_oparg = delta; + } + else + continue; + if (instr->i_oparg > 0xffff) + extended_arg_count++; } - else - continue; - if (instr->i_oparg > 0xffff) - extended_arg_count++; } - } /* XXX: This is an awful hack that could hurt performance, but on the bright side it should work until we come up with a better solution. - In the meantime, should the goto be dropped in favor - of a loop? - The issue is that in the first loop blocksize() is called which calls instrsize() which requires i_oparg be set appropriately. There is a bootstrap problem because @@ -3855,10 +3853,7 @@ ones in jump instructions. So this should converge fairly quickly. */ - if (last_extended_arg_count != extended_arg_count) { - last_extended_arg_count = extended_arg_count; - goto start; - } + } while (last_extended_arg_count != extended_arg_count); } static PyObject * Modified: python/branches/py3k/Tools/pybench/pybench.py ============================================================================== --- python/branches/py3k/Tools/pybench/pybench.py (original) +++ python/branches/py3k/Tools/pybench/pybench.py Wed Nov 25 18:46:26 2009 @@ -228,7 +228,7 @@ raise ValueError('at least one calibration run is required') self.calibration_runs = calibration_runs if timer is not None: - timer = timer + self.timer = timer # Init variables self.times = [] From python-checkins at python.org Wed Nov 25 18:54:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 17:54:15 -0000 Subject: [Python-checkins] r76516 - python/branches/py3k Message-ID: Author: benjamin.peterson Date: Wed Nov 25 18:54:15 2009 New Revision: 76516 Log: Blocked revisions 74523,74715,74721,74733-74734,74798,74825,74832,74845,74849,74873,74936-74937,74962,74964,74981,75017,75022,76053 via svnmerge ........ r74523 | gregory.p.smith | 2009-08-20 04:38:43 -0500 (Thu, 20 Aug 2009) | 2 lines comment typo fix ........ r74715 | ronald.oussoren | 2009-09-08 02:17:10 -0500 (Tue, 08 Sep 2009) | 5 lines This is an update to r74701. How hard can it be to get a configure test right. This patch has already been backported as part of the backport of r74701, which is how I found this problem. ........ r74721 | thomas.heller | 2009-09-08 14:24:36 -0500 (Tue, 08 Sep 2009) | 1 line Make ctypes compile again with older Python versions. ........ r74733 | benjamin.peterson | 2009-09-09 06:40:54 -0500 (Wed, 09 Sep 2009) | 1 line tabbify ........ r74734 | benjamin.peterson | 2009-09-09 06:42:57 -0500 (Wed, 09 Sep 2009) | 1 line revert unintended changes ........ r74798 | ronald.oussoren | 2009-09-15 13:33:33 -0500 (Tue, 15 Sep 2009) | 8 lines MacOSX: detect the architectures supported by Tk.framework and build _tkinter only for those architectures. This replaces the hardcoded solution that is no longer valid now that 64-bit capable versions of Tk are available on OSX. ........ r74825 | ezio.melotti | 2009-09-16 08:14:05 -0500 (Wed, 16 Sep 2009) | 1 line #6879 - fix misstatement about exceptions ........ r74832 | georg.brandl | 2009-09-16 10:57:46 -0500 (Wed, 16 Sep 2009) | 1 line Rewrap long lines. ........ r74845 | georg.brandl | 2009-09-16 15:30:09 -0500 (Wed, 16 Sep 2009) | 5 lines #6844: do not emit DeprecationWarnings on access if Exception.message has been set by the user. This works by always setting it in __dict__, except when it's implicitly set in __init__. ........ r74849 | thomas.wouters | 2009-09-16 15:36:34 -0500 (Wed, 16 Sep 2009) | 4 lines Add news entry for r74841. ........ r74873 | georg.brandl | 2009-09-17 06:48:31 -0500 (Thu, 17 Sep 2009) | 1 line #6844 followup: the warning when setting Exception.message was removed, do not test for it. ........ r74936 | benjamin.peterson | 2009-09-18 16:46:21 -0500 (Fri, 18 Sep 2009) | 1 line backport keyword argument support for bytearray.decode ........ r74937 | benjamin.peterson | 2009-09-18 16:47:27 -0500 (Fri, 18 Sep 2009) | 1 line typo ........ r74962 | ronald.oussoren | 2009-09-20 05:31:22 -0500 (Sun, 20 Sep 2009) | 2 lines Fix for issue 6851: urllib.urlopen crashes in a thread on OSX 10.6 ........ r74964 | ronald.oussoren | 2009-09-20 05:54:07 -0500 (Sun, 20 Sep 2009) | 2 lines Followup for r74962 ........ r74981 | ronald.oussoren | 2009-09-20 15:16:11 -0500 (Sun, 20 Sep 2009) | 3 lines * Make it easier to build custom installers (such as a 3-way universal build) * Upgrade bzip dependency to 1.0.5 ........ r75017 | ronald.oussoren | 2009-09-22 09:24:57 -0500 (Tue, 22 Sep 2009) | 4 lines The 'Navigation Toolbox' is not available at all for 64-bit code, make this explicit in the C code to avoid confusing error messages during the build. ........ r75022 | ronald.oussoren | 2009-09-22 14:27:44 -0500 (Tue, 22 Sep 2009) | 8 lines Half of the fix for issue 6957: ensure that distutils ignores the '-isysroot' option on OSX when the corresponding SDK is not installed. This ensures that the user can compile extensions on OSX 10.6 using the Python.org installer and a default installation of Xcode. ........ r76053 | gregory.p.smith | 2009-11-01 20:03:16 -0600 (Sun, 01 Nov 2009) | 2 lines regenerated from r76052 ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Nov 25 19:16:46 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 18:16:46 -0000 Subject: [Python-checkins] r76517 - in python/trunk/Lib/lib2to3: fixes/fix_imports.py fixes/fix_next.py fixes/fix_renames.py fixes/fix_urllib.py main.py pgen2/tokenize.py refactor.py tests/data/bom.py tests/test_fixers.py tests/test_refactor.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 19:16:46 2009 New Revision: 76517 Log: Merged revisions 76160-76161,76250,76252,76447,76506 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76160 | benjamin.peterson | 2009-11-08 18:53:48 -0600 (Sun, 08 Nov 2009) | 1 line undeprecate the -p option; it's useful for converting python3 sources ........ r76161 | benjamin.peterson | 2009-11-08 19:05:37 -0600 (Sun, 08 Nov 2009) | 1 line simplify condition ........ r76250 | benjamin.peterson | 2009-11-13 16:56:48 -0600 (Fri, 13 Nov 2009) | 1 line fix handling of a utf-8 bom #7313 ........ r76252 | benjamin.peterson | 2009-11-13 16:58:36 -0600 (Fri, 13 Nov 2009) | 1 line remove pdb turd ........ r76447 | benjamin.peterson | 2009-11-22 18:17:40 -0600 (Sun, 22 Nov 2009) | 1 line #7375 fix nested transformations in fix_urllib ........ r76506 | benjamin.peterson | 2009-11-24 18:34:31 -0600 (Tue, 24 Nov 2009) | 1 line use generator expressions in any() ........ Added: python/trunk/Lib/lib2to3/tests/data/bom.py - copied unchanged from r76506, /sandbox/trunk/2to3/lib2to3/tests/data/bom.py Modified: python/trunk/Lib/lib2to3/ (props changed) python/trunk/Lib/lib2to3/fixes/fix_imports.py python/trunk/Lib/lib2to3/fixes/fix_next.py python/trunk/Lib/lib2to3/fixes/fix_renames.py python/trunk/Lib/lib2to3/fixes/fix_urllib.py python/trunk/Lib/lib2to3/main.py python/trunk/Lib/lib2to3/pgen2/tokenize.py python/trunk/Lib/lib2to3/refactor.py python/trunk/Lib/lib2to3/tests/test_fixers.py python/trunk/Lib/lib2to3/tests/test_refactor.py Modified: python/trunk/Lib/lib2to3/fixes/fix_imports.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_imports.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_imports.py Wed Nov 25 19:16:46 2009 @@ -108,7 +108,7 @@ # Module usage could be in the trailer of an attribute lookup, so we # might have nested matches when "bare_with_attr" is present. if "bare_with_attr" not in results and \ - any([match(obj) for obj in attr_chain(node, "parent")]): + any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: python/trunk/Lib/lib2to3/fixes/fix_next.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_next.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_next.py Wed Nov 25 19:16:46 2009 @@ -99,4 +99,4 @@ def is_subtree(root, node): if root == node: return True - return any([is_subtree(c, node) for c in root.children]) + return any(is_subtree(c, node) for c in root.children) Modified: python/trunk/Lib/lib2to3/fixes/fix_renames.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_renames.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_renames.py Wed Nov 25 19:16:46 2009 @@ -49,7 +49,7 @@ match = super(FixRenames, self).match results = match(node) if results: - if any([match(obj) for obj in attr_chain(node, "parent")]): + if any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: python/trunk/Lib/lib2to3/fixes/fix_urllib.py ============================================================================== --- python/trunk/Lib/lib2to3/fixes/fix_urllib.py (original) +++ python/trunk/Lib/lib2to3/fixes/fix_urllib.py Wed Nov 25 19:16:46 2009 @@ -63,7 +63,8 @@ yield """import_name< 'import' dotted_as_name< module_as=%r 'as' any > > """ % old_module - yield """power< module_dot=%r trailer< '.' member=%s > any* > + # bare_with_attr has a special significance for FixImports.match(). + yield """power< bare_with_attr=%r trailer< '.' member=%s > any* > """ % (old_module, members) @@ -150,12 +151,11 @@ def transform_dot(self, node, results): """Transform for calls to module members in code.""" - module_dot = results.get('module_dot') + module_dot = results.get('bare_with_attr') member = results.get('member') - # this may be a list of length one, or just a node + new_name = None if isinstance(member, list): member = member[0] - new_name = None for change in MAPPING[module_dot.value]: if member.value in change[1]: new_name = change[0] @@ -171,7 +171,7 @@ self.transform_import(node, results) elif results.get('mod_member'): self.transform_member(node, results) - elif results.get('module_dot'): + elif results.get('bare_with_attr'): self.transform_dot(node, results) # Renaming and star imports are not supported for these modules. elif results.get('module_star'): Modified: python/trunk/Lib/lib2to3/main.py ============================================================================== --- python/trunk/Lib/lib2to3/main.py (original) +++ python/trunk/Lib/lib2to3/main.py Wed Nov 25 19:16:46 2009 @@ -91,8 +91,7 @@ parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") parser.add_option("-p", "--print-function", action="store_true", - help="DEPRECATED Modify the grammar so that print() is " - "a function") + help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", @@ -104,12 +103,10 @@ # Parse command line arguments refactor_stdin = False + flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") - if options.print_function: - warn("-p is deprecated; " - "detection of from __future__ import print_function is automatic") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: @@ -127,6 +124,8 @@ if options.write: print >> sys.stderr, "Can't write to stdin." return 2 + if options.print_function: + flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO @@ -147,7 +146,7 @@ else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) - rt = StdoutRefactoringTool(sorted(fixer_names), None, sorted(explicit), + rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments Modified: python/trunk/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- python/trunk/Lib/lib2to3/pgen2/tokenize.py (original) +++ python/trunk/Lib/lib2to3/pgen2/tokenize.py Wed Nov 25 19:16:46 2009 @@ -281,9 +281,13 @@ # This behaviour mimics the Python interpreter raise SyntaxError("unknown encoding: " + encoding) - if bom_found and codec.name != 'utf-8': - # This behaviour mimics the Python interpreter - raise SyntaxError('encoding problem: utf-8') + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + raise SyntaxError('encoding problem: utf-8') + else: + # Allow it to be properly encoded and decoded. + encoding = 'utf-8-sig' return encoding first = read_or_stop() Modified: python/trunk/Lib/lib2to3/refactor.py ============================================================================== --- python/trunk/Lib/lib2to3/refactor.py (original) +++ python/trunk/Lib/lib2to3/refactor.py Wed Nov 25 19:16:46 2009 @@ -18,7 +18,6 @@ import operator import collections import StringIO -import warnings from itertools import chain # Local imports @@ -139,26 +138,23 @@ if have_docstring: break have_docstring = True - elif tp == token.NAME: - if value == u"from": + elif tp == token.NAME and value == u"from": + tp, value = advance() + if tp != token.NAME and value != u"__future__": + break + tp, value = advance() + if tp != token.NAME and value != u"import": + break + tp, value = advance() + if tp == token.OP and value == u"(": tp, value = advance() - if tp != token.NAME and value != u"__future__": - break + while tp == token.NAME: + if value == u"print_function": + return True tp, value = advance() - if tp != token.NAME and value != u"import": + if tp != token.OP and value != u",": break tp, value = advance() - if tp == token.OP and value == u"(": - tp, value = advance() - while tp == token.NAME: - if value == u"print_function": - return True - tp, value = advance() - if tp != token.OP and value != u",": - break - tp, value = advance() - else: - break else: break except StopIteration: @@ -172,7 +168,7 @@ class RefactoringTool(object): - _default_options = {} + _default_options = {"print_function" : False} CLASS_PREFIX = "Fix" # The prefix for fixer classes FILE_PREFIX = "fix_" # The prefix for modules with a fixer within @@ -189,15 +185,16 @@ self.explicit = explicit or [] self.options = self._default_options.copy() if options is not None: - if "print_function" in options: - warnings.warn("the 'print_function' option is deprecated", - DeprecationWarning) self.options.update(options) + if self.options["print_function"]: + self.grammar = pygram.python_grammar_no_print_statement + else: + self.grammar = pygram.python_grammar self.errors = [] self.logger = logging.getLogger("RefactoringTool") self.fixer_log = [] self.wrote = False - self.driver = driver.Driver(pygram.python_grammar, + self.driver = driver.Driver(self.grammar, convert=pytree.convert, logger=self.logger) self.pre_order, self.post_order = self.get_fixers() @@ -353,7 +350,7 @@ name, err.__class__.__name__, err) return finally: - self.driver.grammar = pygram.python_grammar + self.driver.grammar = self.grammar self.log_debug("Refactoring %s", name) self.refactor_tree(tree, name) return tree Modified: python/trunk/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_fixers.py (original) +++ python/trunk/Lib/lib2to3/tests/test_fixers.py Wed Nov 25 19:16:46 2009 @@ -1753,6 +1753,8 @@ for old, changes in self.modules.items(): for new, members in changes: for member in members: + new_import = ", ".join([n for (n, mems) + in self.modules[old]]) b = """ import %s foo(%s.%s) @@ -1760,9 +1762,16 @@ a = """ import %s foo(%s.%s) - """ % (", ".join([n for (n, mems) - in self.modules[old]]), - new, member) + """ % (new_import, new, member) + self.check(b, a) + b = """ + import %s + %s.%s(%s.%s) + """ % (old, old, member, old, member) + a = """ + import %s + %s.%s(%s.%s) + """ % (new_import, new, member, new, member) self.check(b, a) Modified: python/trunk/Lib/lib2to3/tests/test_refactor.py ============================================================================== --- python/trunk/Lib/lib2to3/tests/test_refactor.py (original) +++ python/trunk/Lib/lib2to3/tests/test_refactor.py Wed Nov 25 19:16:46 2009 @@ -4,6 +4,7 @@ import sys import os +import codecs import operator import StringIO import tempfile @@ -45,12 +46,10 @@ return refactor.RefactoringTool(fixers, options, explicit) def test_print_function_option(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - refactor.RefactoringTool(_DEFAULT_FIXERS, {"print_function" : True}) - self.assertEqual(len(w), 1) - msg, = w - self.assertTrue(msg.category is DeprecationWarning) + rt = self.rt({"print_function" : True}) + self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement) + self.assertTrue(rt.driver.grammar is + pygram.python_grammar_no_print_statement) def test_fixer_loading_helpers(self): contents = ["explicit", "first", "last", "parrot", "preorder"] @@ -179,10 +178,12 @@ try: rt.refactor_file(test_file, True) - self.assertNotEqual(old_contents, read_file()) + new_contents = read_file() + self.assertNotEqual(old_contents, new_contents) finally: with open(test_file, "wb") as fp: fp.write(old_contents) + return new_contents def test_refactor_file(self): test_file = os.path.join(FIXER_DIR, "parrot_example.py") @@ -223,6 +224,11 @@ fn = os.path.join(TEST_DATA_DIR, "different_encoding.py") self.check_file_refactoring(fn) + def test_bom(self): + fn = os.path.join(TEST_DATA_DIR, "bom.py") + data = self.check_file_refactoring(fn) + self.assertTrue(data.startswith(codecs.BOM_UTF8)) + def test_crlf_newlines(self): old_sep = os.linesep os.linesep = "\r\n" From python-checkins at python.org Wed Nov 25 19:34:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 18:34:43 -0000 Subject: [Python-checkins] r76518 - in python/branches/py3k: Doc/library/calendar.rst Doc/library/functions.rst Doc/library/socketserver.rst Doc/library/string.rst Doc/library/xml.dom.rst Doc/library/zipfile.rst Lib/lib2to3/fixes/fix_imports.py Lib/lib2to3/fixes/fix_next.py Lib/lib2to3/fixes/fix_renames.py Lib/lib2to3/fixes/fix_urllib.py Lib/lib2to3/main.py Lib/lib2to3/pgen2/tokenize.py Lib/lib2to3/refactor.py Lib/lib2to3/tests/data/bom.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_refactor.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 19:34:42 2009 New Revision: 76518 Log: Merged revisions 76259,76326,76376-76377,76430,76471,76517 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76259 | georg.brandl | 2009-11-14 05:50:51 -0600 (Sat, 14 Nov 2009) | 1 line Fix terminology. ................ r76326 | georg.brandl | 2009-11-16 10:44:05 -0600 (Mon, 16 Nov 2009) | 1 line #7302: fix link. ................ r76376 | georg.brandl | 2009-11-18 13:39:14 -0600 (Wed, 18 Nov 2009) | 1 line upcase Python ................ r76377 | georg.brandl | 2009-11-18 14:05:15 -0600 (Wed, 18 Nov 2009) | 1 line Fix markup. ................ r76430 | r.david.murray | 2009-11-20 07:29:43 -0600 (Fri, 20 Nov 2009) | 2 lines Issue 7363: fix indentation in socketserver udpserver example. ................ r76471 | georg.brandl | 2009-11-23 13:53:19 -0600 (Mon, 23 Nov 2009) | 1 line #7345: fix arguments of formatyear(). ................ r76517 | benjamin.peterson | 2009-11-25 12:16:46 -0600 (Wed, 25 Nov 2009) | 29 lines Merged revisions 76160-76161,76250,76252,76447,76506 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76160 | benjamin.peterson | 2009-11-08 18:53:48 -0600 (Sun, 08 Nov 2009) | 1 line undeprecate the -p option; it's useful for converting python3 sources ........ r76161 | benjamin.peterson | 2009-11-08 19:05:37 -0600 (Sun, 08 Nov 2009) | 1 line simplify condition ........ r76250 | benjamin.peterson | 2009-11-13 16:56:48 -0600 (Fri, 13 Nov 2009) | 1 line fix handling of a utf-8 bom #7313 ........ r76252 | benjamin.peterson | 2009-11-13 16:58:36 -0600 (Fri, 13 Nov 2009) | 1 line remove pdb turd ........ r76447 | benjamin.peterson | 2009-11-22 18:17:40 -0600 (Sun, 22 Nov 2009) | 1 line #7375 fix nested transformations in fix_urllib ........ r76506 | benjamin.peterson | 2009-11-24 18:34:31 -0600 (Tue, 24 Nov 2009) | 1 line use generator expressions in any() ........ ................ Added: python/branches/py3k/Lib/lib2to3/tests/data/bom.py - copied unchanged from r76517, /python/trunk/Lib/lib2to3/tests/data/bom.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/calendar.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/socketserver.rst python/branches/py3k/Doc/library/string.rst python/branches/py3k/Doc/library/xml.dom.rst python/branches/py3k/Doc/library/zipfile.rst python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py python/branches/py3k/Lib/lib2to3/fixes/fix_next.py python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py python/branches/py3k/Lib/lib2to3/main.py python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py python/branches/py3k/Lib/lib2to3/refactor.py python/branches/py3k/Lib/lib2to3/tests/test_fixers.py python/branches/py3k/Lib/lib2to3/tests/test_refactor.py Modified: python/branches/py3k/Doc/library/calendar.rst ============================================================================== --- python/branches/py3k/Doc/library/calendar.rst (original) +++ python/branches/py3k/Doc/library/calendar.rst Wed Nov 25 19:34:42 2009 @@ -123,7 +123,7 @@ Print a month's calendar as returned by :meth:`formatmonth`. - .. method:: formatyear(theyear, themonth, w=2, l=1, c=6, m=3) + .. method:: formatyear(theyear, w=2, l=1, c=6, m=3) Return a *m*-column calendar for an entire year as a multi-line string. Optional parameters *w*, *l*, and *c* are for date column width, lines per @@ -152,7 +152,7 @@ used. - .. method:: formatyear(theyear, themonth, width=3) + .. method:: formatyear(theyear, width=3) Return a year's calendar as an HTML table. *width* (defaulting to 3) specifies the number of months per row. Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Wed Nov 25 19:34:42 2009 @@ -176,7 +176,7 @@ .. note:: - When compiling a string with multi-line statements in ``'single'`` or + When compiling a string with multi-line code in ``'single'`` or ``'eval'`` mode, input must be terminated by at least one newline character. This is to facilitate detection of incomplete and complete statements in the :mod:`code` module. Modified: python/branches/py3k/Doc/library/socketserver.rst ============================================================================== --- python/branches/py3k/Doc/library/socketserver.rst (original) +++ python/branches/py3k/Doc/library/socketserver.rst Wed Nov 25 19:34:42 2009 @@ -446,9 +446,9 @@ socket.sendto(data.upper(), self.client_address) if __name__ == "__main__": - HOST, PORT = "localhost", 9999 - server = socketserver.UDPServer((HOST, PORT), MyUDPHandler) - server.serve_forever() + HOST, PORT = "localhost", 9999 + server = socketserver.UDPServer((HOST, PORT), MyUDPHandler) + server.serve_forever() This is the client side:: Modified: python/branches/py3k/Doc/library/string.rst ============================================================================== --- python/branches/py3k/Doc/library/string.rst (original) +++ python/branches/py3k/Doc/library/string.rst Wed Nov 25 19:34:42 2009 @@ -521,13 +521,12 @@ templates containing dangling delimiters, unmatched braces, or placeholders that are not valid Python identifiers. -:class:`Template` instances also provide one public data attribute: + :class:`Template` instances also provide one public data attribute: + .. attribute:: template -.. attribute:: string.template - - This is the object passed to the constructor's *template* argument. In general, - you shouldn't change it, but read-only access is not enforced. + This is the object passed to the constructor's *template* argument. In + general, you shouldn't change it, but read-only access is not enforced. Here is an example of how to use a Template: Modified: python/branches/py3k/Doc/library/xml.dom.rst ============================================================================== --- python/branches/py3k/Doc/library/xml.dom.rst (original) +++ python/branches/py3k/Doc/library/xml.dom.rst Wed Nov 25 19:34:42 2009 @@ -76,7 +76,7 @@ `Document Object Model (DOM) Level 1 Specification `_ The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`. - `Python Language Mapping Specification `_ + `Python Language Mapping Specification `_ This specifies the mapping from OMG IDL to Python. Modified: python/branches/py3k/Doc/library/zipfile.rst ============================================================================== --- python/branches/py3k/Doc/library/zipfile.rst (original) +++ python/branches/py3k/Doc/library/zipfile.rst Wed Nov 25 19:34:42 2009 @@ -19,7 +19,7 @@ (that is ZIP files that are more than 4 GByte in size). It supports decryption of encrypted files in ZIP archives, but it currently cannot create an encrypted file. Decryption is extremely slow as it is -implemented in native python rather than C. +implemented in native Python rather than C. For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and :mod:`tarfile` modules. Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_imports.py Wed Nov 25 19:34:42 2009 @@ -108,7 +108,7 @@ # Module usage could be in the trailer of an attribute lookup, so we # might have nested matches when "bare_with_attr" is present. if "bare_with_attr" not in results and \ - any([match(obj) for obj in attr_chain(node, "parent")]): + any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_next.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_next.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_next.py Wed Nov 25 19:34:42 2009 @@ -99,4 +99,4 @@ def is_subtree(root, node): if root == node: return True - return any([is_subtree(c, node) for c in root.children]) + return any(is_subtree(c, node) for c in root.children) Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_renames.py Wed Nov 25 19:34:42 2009 @@ -49,7 +49,7 @@ match = super(FixRenames, self).match results = match(node) if results: - if any([match(obj) for obj in attr_chain(node, "parent")]): + if any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py (original) +++ python/branches/py3k/Lib/lib2to3/fixes/fix_urllib.py Wed Nov 25 19:34:42 2009 @@ -63,7 +63,8 @@ yield """import_name< 'import' dotted_as_name< module_as=%r 'as' any > > """ % old_module - yield """power< module_dot=%r trailer< '.' member=%s > any* > + # bare_with_attr has a special significance for FixImports.match(). + yield """power< bare_with_attr=%r trailer< '.' member=%s > any* > """ % (old_module, members) @@ -150,12 +151,11 @@ def transform_dot(self, node, results): """Transform for calls to module members in code.""" - module_dot = results.get('module_dot') + module_dot = results.get('bare_with_attr') member = results.get('member') - # this may be a list of length one, or just a node + new_name = None if isinstance(member, list): member = member[0] - new_name = None for change in MAPPING[module_dot.value]: if member.value in change[1]: new_name = change[0] @@ -171,7 +171,7 @@ self.transform_import(node, results) elif results.get('mod_member'): self.transform_member(node, results) - elif results.get('module_dot'): + elif results.get('bare_with_attr'): self.transform_dot(node, results) # Renaming and star imports are not supported for these modules. elif results.get('module_star'): Modified: python/branches/py3k/Lib/lib2to3/main.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/main.py (original) +++ python/branches/py3k/Lib/lib2to3/main.py Wed Nov 25 19:34:42 2009 @@ -90,8 +90,7 @@ parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") parser.add_option("-p", "--print-function", action="store_true", - help="DEPRECATED Modify the grammar so that print() is " - "a function") + help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", @@ -103,12 +102,10 @@ # Parse command line arguments refactor_stdin = False + flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") - if options.print_function: - warn("-p is deprecated; " - "detection of from __future__ import print_function is automatic") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: @@ -126,6 +123,8 @@ if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 + if options.print_function: + flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO @@ -146,7 +145,7 @@ else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) - rt = StdoutRefactoringTool(sorted(fixer_names), None, sorted(explicit), + rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments Modified: python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py (original) +++ python/branches/py3k/Lib/lib2to3/pgen2/tokenize.py Wed Nov 25 19:34:42 2009 @@ -283,9 +283,13 @@ # This behaviour mimics the Python interpreter raise SyntaxError("unknown encoding: " + encoding) - if bom_found and codec.name != 'utf-8': - # This behaviour mimics the Python interpreter - raise SyntaxError('encoding problem: utf-8') + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + raise SyntaxError('encoding problem: utf-8') + else: + # Allow it to be properly encoded and decoded. + encoding = 'utf-8-sig' return encoding first = read_or_stop() Modified: python/branches/py3k/Lib/lib2to3/refactor.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/refactor.py (original) +++ python/branches/py3k/Lib/lib2to3/refactor.py Wed Nov 25 19:34:42 2009 @@ -18,7 +18,6 @@ import operator import collections import io -import warnings from itertools import chain # Local imports @@ -139,26 +138,23 @@ if have_docstring: break have_docstring = True - elif tp == token.NAME: - if value == "from": + elif tp == token.NAME and value == "from": + tp, value = advance() + if tp != token.NAME and value != "__future__": + break + tp, value = advance() + if tp != token.NAME and value != "import": + break + tp, value = advance() + if tp == token.OP and value == "(": tp, value = advance() - if tp != token.NAME and value != "__future__": - break + while tp == token.NAME: + if value == "print_function": + return True tp, value = advance() - if tp != token.NAME and value != "import": + if tp != token.OP and value != ",": break tp, value = advance() - if tp == token.OP and value == "(": - tp, value = advance() - while tp == token.NAME: - if value == "print_function": - return True - tp, value = advance() - if tp != token.OP and value != ",": - break - tp, value = advance() - else: - break else: break except StopIteration: @@ -172,7 +168,7 @@ class RefactoringTool(object): - _default_options = {} + _default_options = {"print_function" : False} CLASS_PREFIX = "Fix" # The prefix for fixer classes FILE_PREFIX = "fix_" # The prefix for modules with a fixer within @@ -189,15 +185,16 @@ self.explicit = explicit or [] self.options = self._default_options.copy() if options is not None: - if "print_function" in options: - warnings.warn("the 'print_function' option is deprecated", - DeprecationWarning) self.options.update(options) + if self.options["print_function"]: + self.grammar = pygram.python_grammar_no_print_statement + else: + self.grammar = pygram.python_grammar self.errors = [] self.logger = logging.getLogger("RefactoringTool") self.fixer_log = [] self.wrote = False - self.driver = driver.Driver(pygram.python_grammar, + self.driver = driver.Driver(self.grammar, convert=pytree.convert, logger=self.logger) self.pre_order, self.post_order = self.get_fixers() @@ -353,7 +350,7 @@ name, err.__class__.__name__, err) return finally: - self.driver.grammar = pygram.python_grammar + self.driver.grammar = self.grammar self.log_debug("Refactoring %s", name) self.refactor_tree(tree, name) return tree Modified: python/branches/py3k/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_fixers.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_fixers.py Wed Nov 25 19:34:42 2009 @@ -1753,6 +1753,8 @@ for old, changes in self.modules.items(): for new, members in changes: for member in members: + new_import = ", ".join([n for (n, mems) + in self.modules[old]]) b = """ import %s foo(%s.%s) @@ -1760,9 +1762,16 @@ a = """ import %s foo(%s.%s) - """ % (", ".join([n for (n, mems) - in self.modules[old]]), - new, member) + """ % (new_import, new, member) + self.check(b, a) + b = """ + import %s + %s.%s(%s.%s) + """ % (old, old, member, old, member) + a = """ + import %s + %s.%s(%s.%s) + """ % (new_import, new, member, new, member) self.check(b, a) Modified: python/branches/py3k/Lib/lib2to3/tests/test_refactor.py ============================================================================== --- python/branches/py3k/Lib/lib2to3/tests/test_refactor.py (original) +++ python/branches/py3k/Lib/lib2to3/tests/test_refactor.py Wed Nov 25 19:34:42 2009 @@ -4,6 +4,7 @@ import sys import os +import codecs import operator import io import tempfile @@ -45,12 +46,10 @@ return refactor.RefactoringTool(fixers, options, explicit) def test_print_function_option(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - refactor.RefactoringTool(_DEFAULT_FIXERS, {"print_function" : True}) - self.assertEqual(len(w), 1) - msg, = w - self.assertTrue(msg.category is DeprecationWarning) + rt = self.rt({"print_function" : True}) + self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement) + self.assertTrue(rt.driver.grammar is + pygram.python_grammar_no_print_statement) def test_fixer_loading_helpers(self): contents = ["explicit", "first", "last", "parrot", "preorder"] @@ -179,10 +178,12 @@ try: rt.refactor_file(test_file, True) - self.assertNotEqual(old_contents, read_file()) + new_contents = read_file() + self.assertNotEqual(old_contents, new_contents) finally: with open(test_file, "wb") as fp: fp.write(old_contents) + return new_contents def test_refactor_file(self): test_file = os.path.join(FIXER_DIR, "parrot_example.py") @@ -223,6 +224,11 @@ fn = os.path.join(TEST_DATA_DIR, "different_encoding.py") self.check_file_refactoring(fn) + def test_bom(self): + fn = os.path.join(TEST_DATA_DIR, "bom.py") + data = self.check_file_refactoring(fn) + self.assertTrue(data.startswith(codecs.BOM_UTF8)) + def test_crlf_newlines(self): old_sep = os.linesep os.linesep = "\r\n" From python-checkins at python.org Wed Nov 25 19:37:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 18:37:13 -0000 Subject: [Python-checkins] r76519 - in python/branches/release31-maint: Doc/library/calendar.rst Doc/library/socketserver.rst Doc/library/string.rst Doc/library/xml.dom.rst Doc/library/zipfile.rst Lib/lib2to3/fixes/fix_imports.py Lib/lib2to3/fixes/fix_next.py Lib/lib2to3/fixes/fix_renames.py Lib/lib2to3/fixes/fix_urllib.py Lib/lib2to3/main.py Lib/lib2to3/pgen2/tokenize.py Lib/lib2to3/refactor.py Lib/lib2to3/tests/data/bom.py Lib/lib2to3/tests/test_fixers.py Lib/lib2to3/tests/test_refactor.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 19:37:12 2009 New Revision: 76519 Log: Merged revisions 76518 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76518 | benjamin.peterson | 2009-11-25 12:34:42 -0600 (Wed, 25 Nov 2009) | 60 lines Merged revisions 76259,76326,76376-76377,76430,76471,76517 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ................ r76259 | georg.brandl | 2009-11-14 05:50:51 -0600 (Sat, 14 Nov 2009) | 1 line Fix terminology. ................ r76326 | georg.brandl | 2009-11-16 10:44:05 -0600 (Mon, 16 Nov 2009) | 1 line #7302: fix link. ................ r76376 | georg.brandl | 2009-11-18 13:39:14 -0600 (Wed, 18 Nov 2009) | 1 line upcase Python ................ r76377 | georg.brandl | 2009-11-18 14:05:15 -0600 (Wed, 18 Nov 2009) | 1 line Fix markup. ................ r76430 | r.david.murray | 2009-11-20 07:29:43 -0600 (Fri, 20 Nov 2009) | 2 lines Issue 7363: fix indentation in socketserver udpserver example. ................ r76471 | georg.brandl | 2009-11-23 13:53:19 -0600 (Mon, 23 Nov 2009) | 1 line #7345: fix arguments of formatyear(). ................ r76517 | benjamin.peterson | 2009-11-25 12:16:46 -0600 (Wed, 25 Nov 2009) | 29 lines Merged revisions 76160-76161,76250,76252,76447,76506 via svnmerge from svn+ssh://pythondev at svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r76160 | benjamin.peterson | 2009-11-08 18:53:48 -0600 (Sun, 08 Nov 2009) | 1 line undeprecate the -p option; it's useful for converting python3 sources ........ r76161 | benjamin.peterson | 2009-11-08 19:05:37 -0600 (Sun, 08 Nov 2009) | 1 line simplify condition ........ r76250 | benjamin.peterson | 2009-11-13 16:56:48 -0600 (Fri, 13 Nov 2009) | 1 line fix handling of a utf-8 bom #7313 ........ r76252 | benjamin.peterson | 2009-11-13 16:58:36 -0600 (Fri, 13 Nov 2009) | 1 line remove pdb turd ........ r76447 | benjamin.peterson | 2009-11-22 18:17:40 -0600 (Sun, 22 Nov 2009) | 1 line #7375 fix nested transformations in fix_urllib ........ r76506 | benjamin.peterson | 2009-11-24 18:34:31 -0600 (Tue, 24 Nov 2009) | 1 line use generator expressions in any() ........ ................ ................ Added: python/branches/release31-maint/Lib/lib2to3/tests/data/bom.py - copied unchanged from r76518, /python/branches/py3k/Lib/lib2to3/tests/data/bom.py Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Doc/library/calendar.rst python/branches/release31-maint/Doc/library/socketserver.rst python/branches/release31-maint/Doc/library/string.rst python/branches/release31-maint/Doc/library/xml.dom.rst python/branches/release31-maint/Doc/library/zipfile.rst python/branches/release31-maint/Lib/lib2to3/fixes/fix_imports.py python/branches/release31-maint/Lib/lib2to3/fixes/fix_next.py python/branches/release31-maint/Lib/lib2to3/fixes/fix_renames.py python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py python/branches/release31-maint/Lib/lib2to3/main.py python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py python/branches/release31-maint/Lib/lib2to3/refactor.py python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py Modified: python/branches/release31-maint/Doc/library/calendar.rst ============================================================================== --- python/branches/release31-maint/Doc/library/calendar.rst (original) +++ python/branches/release31-maint/Doc/library/calendar.rst Wed Nov 25 19:37:12 2009 @@ -123,7 +123,7 @@ Print a month's calendar as returned by :meth:`formatmonth`. - .. method:: formatyear(theyear, themonth, w=2, l=1, c=6, m=3) + .. method:: formatyear(theyear, w=2, l=1, c=6, m=3) Return a *m*-column calendar for an entire year as a multi-line string. Optional parameters *w*, *l*, and *c* are for date column width, lines per @@ -152,7 +152,7 @@ used. - .. method:: formatyear(theyear, themonth, width=3) + .. method:: formatyear(theyear, width=3) Return a year's calendar as an HTML table. *width* (defaulting to 3) specifies the number of months per row. Modified: python/branches/release31-maint/Doc/library/socketserver.rst ============================================================================== --- python/branches/release31-maint/Doc/library/socketserver.rst (original) +++ python/branches/release31-maint/Doc/library/socketserver.rst Wed Nov 25 19:37:12 2009 @@ -447,9 +447,9 @@ socket.sendto(data.upper(), self.client_address) if __name__ == "__main__": - HOST, PORT = "localhost", 9999 - server = socketserver.UDPServer((HOST, PORT), MyUDPHandler) - server.serve_forever() + HOST, PORT = "localhost", 9999 + server = socketserver.UDPServer((HOST, PORT), MyUDPHandler) + server.serve_forever() This is the client side:: Modified: python/branches/release31-maint/Doc/library/string.rst ============================================================================== --- python/branches/release31-maint/Doc/library/string.rst (original) +++ python/branches/release31-maint/Doc/library/string.rst Wed Nov 25 19:37:12 2009 @@ -521,13 +521,12 @@ templates containing dangling delimiters, unmatched braces, or placeholders that are not valid Python identifiers. -:class:`Template` instances also provide one public data attribute: + :class:`Template` instances also provide one public data attribute: + .. attribute:: template -.. attribute:: string.template - - This is the object passed to the constructor's *template* argument. In general, - you shouldn't change it, but read-only access is not enforced. + This is the object passed to the constructor's *template* argument. In + general, you shouldn't change it, but read-only access is not enforced. Here is an example of how to use a Template: Modified: python/branches/release31-maint/Doc/library/xml.dom.rst ============================================================================== --- python/branches/release31-maint/Doc/library/xml.dom.rst (original) +++ python/branches/release31-maint/Doc/library/xml.dom.rst Wed Nov 25 19:37:12 2009 @@ -76,7 +76,7 @@ `Document Object Model (DOM) Level 1 Specification `_ The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`. - `Python Language Mapping Specification `_ + `Python Language Mapping Specification `_ This specifies the mapping from OMG IDL to Python. Modified: python/branches/release31-maint/Doc/library/zipfile.rst ============================================================================== --- python/branches/release31-maint/Doc/library/zipfile.rst (original) +++ python/branches/release31-maint/Doc/library/zipfile.rst Wed Nov 25 19:37:12 2009 @@ -19,7 +19,7 @@ (that is ZIP files that are more than 4 GByte in size). It supports decryption of encrypted files in ZIP archives, but it currently cannot create an encrypted file. Decryption is extremely slow as it is -implemented in native python rather than C. +implemented in native Python rather than C. For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and :mod:`tarfile` modules. Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_imports.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_imports.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_imports.py Wed Nov 25 19:37:12 2009 @@ -108,7 +108,7 @@ # Module usage could be in the trailer of an attribute lookup, so we # might have nested matches when "bare_with_attr" is present. if "bare_with_attr" not in results and \ - any([match(obj) for obj in attr_chain(node, "parent")]): + any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_next.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_next.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_next.py Wed Nov 25 19:37:12 2009 @@ -99,4 +99,4 @@ def is_subtree(root, node): if root == node: return True - return any([is_subtree(c, node) for c in root.children]) + return any(is_subtree(c, node) for c in root.children) Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_renames.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_renames.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_renames.py Wed Nov 25 19:37:12 2009 @@ -49,7 +49,7 @@ match = super(FixRenames, self).match results = match(node) if results: - if any([match(obj) for obj in attr_chain(node, "parent")]): + if any(match(obj) for obj in attr_chain(node, "parent")): return False return results return False Modified: python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py (original) +++ python/branches/release31-maint/Lib/lib2to3/fixes/fix_urllib.py Wed Nov 25 19:37:12 2009 @@ -63,7 +63,8 @@ yield """import_name< 'import' dotted_as_name< module_as=%r 'as' any > > """ % old_module - yield """power< module_dot=%r trailer< '.' member=%s > any* > + # bare_with_attr has a special significance for FixImports.match(). + yield """power< bare_with_attr=%r trailer< '.' member=%s > any* > """ % (old_module, members) @@ -150,12 +151,11 @@ def transform_dot(self, node, results): """Transform for calls to module members in code.""" - module_dot = results.get('module_dot') + module_dot = results.get('bare_with_attr') member = results.get('member') - # this may be a list of length one, or just a node + new_name = None if isinstance(member, list): member = member[0] - new_name = None for change in MAPPING[module_dot.value]: if member.value in change[1]: new_name = change[0] @@ -171,7 +171,7 @@ self.transform_import(node, results) elif results.get('mod_member'): self.transform_member(node, results) - elif results.get('module_dot'): + elif results.get('bare_with_attr'): self.transform_dot(node, results) # Renaming and star imports are not supported for these modules. elif results.get('module_star'): Modified: python/branches/release31-maint/Lib/lib2to3/main.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/main.py (original) +++ python/branches/release31-maint/Lib/lib2to3/main.py Wed Nov 25 19:37:12 2009 @@ -90,8 +90,7 @@ parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") parser.add_option("-p", "--print-function", action="store_true", - help="DEPRECATED Modify the grammar so that print() is " - "a function") + help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", @@ -103,12 +102,10 @@ # Parse command line arguments refactor_stdin = False + flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") - if options.print_function: - warn("-p is deprecated; " - "detection of from __future__ import print_function is automatic") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: @@ -126,6 +123,8 @@ if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 + if options.print_function: + flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO @@ -146,7 +145,7 @@ else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) - rt = StdoutRefactoringTool(sorted(fixer_names), None, sorted(explicit), + rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments Modified: python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py (original) +++ python/branches/release31-maint/Lib/lib2to3/pgen2/tokenize.py Wed Nov 25 19:37:12 2009 @@ -283,9 +283,13 @@ # This behaviour mimics the Python interpreter raise SyntaxError("unknown encoding: " + encoding) - if bom_found and codec.name != 'utf-8': - # This behaviour mimics the Python interpreter - raise SyntaxError('encoding problem: utf-8') + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + raise SyntaxError('encoding problem: utf-8') + else: + # Allow it to be properly encoded and decoded. + encoding = 'utf-8-sig' return encoding first = read_or_stop() Modified: python/branches/release31-maint/Lib/lib2to3/refactor.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/refactor.py (original) +++ python/branches/release31-maint/Lib/lib2to3/refactor.py Wed Nov 25 19:37:12 2009 @@ -18,7 +18,6 @@ import operator import collections import io -import warnings from itertools import chain # Local imports @@ -139,26 +138,23 @@ if have_docstring: break have_docstring = True - elif tp == token.NAME: - if value == "from": + elif tp == token.NAME and value == "from": + tp, value = advance() + if tp != token.NAME and value != "__future__": + break + tp, value = advance() + if tp != token.NAME and value != "import": + break + tp, value = advance() + if tp == token.OP and value == "(": tp, value = advance() - if tp != token.NAME and value != "__future__": - break + while tp == token.NAME: + if value == "print_function": + return True tp, value = advance() - if tp != token.NAME and value != "import": + if tp != token.OP and value != ",": break tp, value = advance() - if tp == token.OP and value == "(": - tp, value = advance() - while tp == token.NAME: - if value == "print_function": - return True - tp, value = advance() - if tp != token.OP and value != ",": - break - tp, value = advance() - else: - break else: break except StopIteration: @@ -172,7 +168,7 @@ class RefactoringTool(object): - _default_options = {} + _default_options = {"print_function" : False} CLASS_PREFIX = "Fix" # The prefix for fixer classes FILE_PREFIX = "fix_" # The prefix for modules with a fixer within @@ -189,15 +185,16 @@ self.explicit = explicit or [] self.options = self._default_options.copy() if options is not None: - if "print_function" in options: - warnings.warn("the 'print_function' option is deprecated", - DeprecationWarning) self.options.update(options) + if self.options["print_function"]: + self.grammar = pygram.python_grammar_no_print_statement + else: + self.grammar = pygram.python_grammar self.errors = [] self.logger = logging.getLogger("RefactoringTool") self.fixer_log = [] self.wrote = False - self.driver = driver.Driver(pygram.python_grammar, + self.driver = driver.Driver(self.grammar, convert=pytree.convert, logger=self.logger) self.pre_order, self.post_order = self.get_fixers() @@ -353,7 +350,7 @@ name, err.__class__.__name__, err) return finally: - self.driver.grammar = pygram.python_grammar + self.driver.grammar = self.grammar self.log_debug("Refactoring %s", name) self.refactor_tree(tree, name) return tree Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_fixers.py Wed Nov 25 19:37:12 2009 @@ -1753,6 +1753,8 @@ for old, changes in self.modules.items(): for new, members in changes: for member in members: + new_import = ", ".join([n for (n, mems) + in self.modules[old]]) b = """ import %s foo(%s.%s) @@ -1760,9 +1762,16 @@ a = """ import %s foo(%s.%s) - """ % (", ".join([n for (n, mems) - in self.modules[old]]), - new, member) + """ % (new_import, new, member) + self.check(b, a) + b = """ + import %s + %s.%s(%s.%s) + """ % (old, old, member, old, member) + a = """ + import %s + %s.%s(%s.%s) + """ % (new_import, new, member, new, member) self.check(b, a) Modified: python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py ============================================================================== --- python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py (original) +++ python/branches/release31-maint/Lib/lib2to3/tests/test_refactor.py Wed Nov 25 19:37:12 2009 @@ -4,6 +4,7 @@ import sys import os +import codecs import operator import io import tempfile @@ -45,12 +46,10 @@ return refactor.RefactoringTool(fixers, options, explicit) def test_print_function_option(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - refactor.RefactoringTool(_DEFAULT_FIXERS, {"print_function" : True}) - self.assertEqual(len(w), 1) - msg, = w - self.assertTrue(msg.category is DeprecationWarning) + rt = self.rt({"print_function" : True}) + self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement) + self.assertTrue(rt.driver.grammar is + pygram.python_grammar_no_print_statement) def test_fixer_loading_helpers(self): contents = ["explicit", "first", "last", "parrot", "preorder"] @@ -179,10 +178,12 @@ try: rt.refactor_file(test_file, True) - self.assertNotEqual(old_contents, read_file()) + new_contents = read_file() + self.assertNotEqual(old_contents, new_contents) finally: with open(test_file, "wb") as fp: fp.write(old_contents) + return new_contents def test_refactor_file(self): test_file = os.path.join(FIXER_DIR, "parrot_example.py") @@ -223,6 +224,11 @@ fn = os.path.join(TEST_DATA_DIR, "different_encoding.py") self.check_file_refactoring(fn) + def test_bom(self): + fn = os.path.join(TEST_DATA_DIR, "bom.py") + data = self.check_file_refactoring(fn) + self.assertTrue(data.startswith(codecs.BOM_UTF8)) + def test_crlf_newlines(self): old_sep = os.linesep os.linesep = "\r\n" From python-checkins at python.org Wed Nov 25 19:38:12 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 25 Nov 2009 18:38:12 -0000 Subject: [Python-checkins] r76520 - python/branches/py3k/Lib/runpy.py Message-ID: Author: benjamin.peterson Date: Wed Nov 25 19:38:11 2009 New Revision: 76520 Log: fix test checking for error message Modified: python/branches/py3k/Lib/runpy.py Modified: python/branches/py3k/Lib/runpy.py ============================================================================== --- python/branches/py3k/Lib/runpy.py (original) +++ python/branches/py3k/Lib/runpy.py Wed Nov 25 19:38:11 2009 @@ -147,7 +147,7 @@ else: # For directories/zipfiles, let the user # know what the code was looking for - info = "can't find '__main__.py' in %r" % sys.argv[0] + info = "can't find '__main__' module in %r" % sys.argv[0] msg = "%s: %s" % (sys.executable, info) sys.exit(msg) pkg_name = mod_name.rpartition('.')[0] From python-checkins at python.org Wed Nov 25 19:38:24 2009 From: python-checkins at python.org (barry.warsaw) Date: Wed, 25 Nov 2009 18:38:24 -0000 Subject: [Python-checkins] r76521 - python/branches/release26-maint/Lib/email/utils.py Message-ID: Author: barry.warsaw Date: Wed Nov 25 19:38:24 2009 New Revision: 76521 Log: Add mktime_tz to __all__. It's documented as being available in email.utils. Modified: python/branches/release26-maint/Lib/email/utils.py Modified: python/branches/release26-maint/Lib/email/utils.py ============================================================================== --- python/branches/release26-maint/Lib/email/utils.py (original) +++ python/branches/release26-maint/Lib/email/utils.py Wed Nov 25 19:38:24 2009 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001-2009 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig at python.org @@ -13,6 +13,7 @@ 'formatdate', 'getaddresses', 'make_msgid', + 'mktime_tz', 'parseaddr', 'parsedate', 'parsedate_tz', From python-checkins at python.org Wed Nov 25 19:38:33 2009 From: python-checkins at python.org (barry.warsaw) Date: Wed, 25 Nov 2009 18:38:33 -0000 Subject: [Python-checkins] r76522 - python/trunk/Lib/email/utils.py Message-ID: Author: barry.warsaw Date: Wed Nov 25 19:38:32 2009 New Revision: 76522 Log: Add mktime_tz to __all__. It's documented as being available in email.utils. Modified: python/trunk/Lib/email/utils.py Modified: python/trunk/Lib/email/utils.py ============================================================================== --- python/trunk/Lib/email/utils.py (original) +++ python/trunk/Lib/email/utils.py Wed Nov 25 19:38:32 2009 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 Python Software Foundation +# Copyright (C) 2001-2009 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig at python.org @@ -13,6 +13,7 @@ 'formatdate', 'getaddresses', 'make_msgid', + 'mktime_tz', 'parseaddr', 'parsedate', 'parsedate_tz', From python-checkins at python.org Wed Nov 25 19:45:05 2009 From: python-checkins at python.org (barry.warsaw) Date: Wed, 25 Nov 2009 18:45:05 -0000 Subject: [Python-checkins] r76523 - python/branches/release31-maint/Lib/email/utils.py Message-ID: Author: barry.warsaw Date: Wed Nov 25 19:45:04 2009 New Revision: 76523 Log: Add mktime_tz to __all__. It's documented as being available in email.utils. Modified: python/branches/release31-maint/Lib/email/utils.py Modified: python/branches/release31-maint/Lib/email/utils.py ============================================================================== --- python/branches/release31-maint/Lib/email/utils.py (original) +++ python/branches/release31-maint/Lib/email/utils.py Wed Nov 25 19:45:04 2009 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001-2009 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig at python.org @@ -13,6 +13,7 @@ 'formatdate', 'getaddresses', 'make_msgid', + 'mktime_tz', 'parseaddr', 'parsedate', 'parsedate_tz', From python-checkins at python.org Wed Nov 25 19:45:16 2009 From: python-checkins at python.org (barry.warsaw) Date: Wed, 25 Nov 2009 18:45:16 -0000 Subject: [Python-checkins] r76524 - python/branches/py3k/Lib/email/utils.py Message-ID: Author: barry.warsaw Date: Wed Nov 25 19:45:15 2009 New Revision: 76524 Log: Add mktime_tz to __all__. It's documented as being available in email.utils. Modified: python/branches/py3k/Lib/email/utils.py Modified: python/branches/py3k/Lib/email/utils.py ============================================================================== --- python/branches/py3k/Lib/email/utils.py (original) +++ python/branches/py3k/Lib/email/utils.py Wed Nov 25 19:45:15 2009 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2007 Python Software Foundation +# Copyright (C) 2001-2009 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig at python.org @@ -13,6 +13,7 @@ 'formatdate', 'getaddresses', 'make_msgid', + 'mktime_tz', 'parseaddr', 'parsedate', 'parsedate_tz', From python-checkins at python.org Wed Nov 25 19:55:32 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 25 Nov 2009 18:55:32 -0000 Subject: [Python-checkins] r76525 - in python/branches/py3k: Lib/test/test_ssl.py Misc/NEWS Modules/_ssl.c Message-ID: Author: antoine.pitrou Date: Wed Nov 25 19:55:32 2009 New Revision: 76525 Log: Merged revisions 75529 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r75529 | antoine.pitrou | 2009-10-19 19:59:07 +0200 (lun., 19 oct. 2009) | 5 lines Issue #7133: SSL objects now support the new buffer API. This fixes the test_ssl failure. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_ssl.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ssl.c Modified: python/branches/py3k/Lib/test/test_ssl.py ============================================================================== --- python/branches/py3k/Lib/test/test_ssl.py (original) +++ python/branches/py3k/Lib/test/test_ssl.py Wed Nov 25 19:55:32 2009 @@ -651,21 +651,23 @@ except Exception as x: raise support.TestFailed("Unexpected exception: " + str(x)) else: - if connectionchatty: - if support.verbose: - sys.stdout.write( - " client: sending %s...\n" % (repr(indata))) - s.write(indata.encode('ASCII', 'strict')) - outdata = s.read() - if connectionchatty: - if support.verbose: - sys.stdout.write(" client: read %s\n" % repr(outdata)) - outdata = str(outdata, 'ASCII', 'strict') - if outdata != indata.lower(): - raise support.TestFailed( - "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n" - % (repr(outdata[:min(len(outdata),20)]), len(outdata), - repr(indata[:min(len(indata),20)].lower()), len(indata))) + bindata = indata.encode('ASCII', 'strict') + for arg in [bindata, bytearray(bindata), memoryview(bindata)]: + if connectionchatty: + if support.verbose: + sys.stdout.write( + " client: sending %s...\n" % (repr(indata))) + s.write(arg) + outdata = s.read() + if connectionchatty: + if support.verbose: + sys.stdout.write(" client: read %s\n" % repr(outdata)) + outdata = str(outdata, 'ASCII', 'strict') + if outdata != indata.lower(): + raise support.TestFailed( + "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n" + % (repr(outdata[:min(len(outdata),20)]), len(outdata), + repr(indata[:min(len(indata),20)].lower()), len(indata))) s.write("over\n".encode("ASCII", "strict")) if connectionchatty: if support.verbose: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Nov 25 19:55:32 2009 @@ -140,6 +140,8 @@ Library ------- +- Issue #7133: SSL objects now support the new buffer API. + - Issue #1488943: difflib.Differ() doesn't always add hints for tab characters - Issue #6123: tarfile now opens empty archives correctly and consistently Modified: python/branches/py3k/Modules/_ssl.c ============================================================================== --- python/branches/py3k/Modules/_ssl.c (original) +++ python/branches/py3k/Modules/_ssl.c Wed Nov 25 19:55:32 2009 @@ -1146,9 +1146,8 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) { - char *data; + Py_buffer buf; int len; - int count; int sockstate; int err; int nonblocking; @@ -1161,7 +1160,7 @@ return NULL; } - if (!PyArg_ParseTuple(args, "y#:write", &data, &count)) + if (!PyArg_ParseTuple(args, "y*:write", &buf)) return NULL; /* just in case the blocking state of the socket has been changed */ @@ -1173,24 +1172,24 @@ if (sockstate == SOCKET_HAS_TIMED_OUT) { PyErr_SetString(PySSLErrorObject, "The write operation timed out"); - return NULL; + goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed."); - return NULL; + goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select()."); - return NULL; + goto error; } do { err = 0; PySSL_BEGIN_ALLOW_THREADS - len = SSL_write(self->ssl, data, count); + len = SSL_write(self->ssl, buf.buf, buf.len); err = SSL_get_error(self->ssl, len); PySSL_END_ALLOW_THREADS - if(PyErr_CheckSignals()) { - return NULL; + if (PyErr_CheckSignals()) { + goto error; } if (err == SSL_ERROR_WANT_READ) { sockstate = @@ -1204,19 +1203,25 @@ if (sockstate == SOCKET_HAS_TIMED_OUT) { PyErr_SetString(PySSLErrorObject, "The write operation timed out"); - return NULL; + goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed."); - return NULL; + goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { break; } } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); + + PyBuffer_Release(&buf); if (len > 0) return PyLong_FromLong(len); else return PySSL_SetError(self, len, __FILE__, __LINE__); + +error: + PyBuffer_Release(&buf); + return NULL; } PyDoc_STRVAR(PySSL_SSLwrite_doc, From python-checkins at python.org Wed Nov 25 20:06:08 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 19:06:08 -0000 Subject: [Python-checkins] r76526 - peps/trunk/pep-0391.txt Message-ID: Author: vinay.sajip Date: Wed Nov 25 20:06:08 2009 New Revision: 76526 Log: Added section on changes to socket listener implementation. Modified: peps/trunk/pep-0391.txt Modified: peps/trunk/pep-0391.txt ============================================================================== --- peps/trunk/pep-0391.txt (original) +++ peps/trunk/pep-0391.txt Wed Nov 25 20:06:08 2009 @@ -611,6 +611,16 @@ would be bound to the subclass, and then ``dictConfig()`` could be called exactly as in the default, uncustomized state. +Change to Socket Listener Implementation +======================================== + +The existing socket listener implementation will be modified as +follows: when a configuration message is received, an attempt will be +made to deserialize to a dictionary using the json module. If this +step fails, the message will be assumed to be in the fileConfig format +and processed as before. If serialization is successful, then +``dictConfig()`` will be called to process the resulting dictionary. + Configuration Errors ==================== From python-checkins at python.org Wed Nov 25 21:57:25 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 25 Nov 2009 20:57:25 -0000 Subject: [Python-checkins] r76527 - peps/trunk/pep-0391.txt Message-ID: Author: vinay.sajip Date: Wed Nov 25 21:57:24 2009 New Revision: 76527 Log: Added links to community discussions and reference implementation. Modified: peps/trunk/pep-0391.txt Modified: peps/trunk/pep-0391.txt ============================================================================== --- peps/trunk/pep-0391.txt (original) +++ peps/trunk/pep-0391.txt Wed Nov 25 21:57:24 2009 @@ -644,6 +644,41 @@ * Inability to resolve to an internal or external object +Discussion in the community +=========================== + +The PEP has been announced on python-dev and python-list. While there +hasn't been a huge amount of discussion, this is perhaps to be +expected for a niche topic. + +Discussion threads on python-dev: + +http://mail.python.org/pipermail/python-dev/2009-October/092695.html +http://mail.python.org/pipermail/python-dev/2009-October/092782.html +http://mail.python.org/pipermail/python-dev/2009-October/093062.html + +And on python-list: + +http://mail.python.org/pipermail/python-list/2009-October/1223658.html +http://mail.python.org/pipermail/python-list/2009-October/1224228.html + +There have been some comments in favour of the proposal, no +objections to the proposal as a whole, and some questions and +objections about specific details. These are believed by the author +to have been addressed by making changes to the PEP. + + +Reference implementation +======================== + +A reference implementation of the changes is available as a module +dictconfig.py with accompanying unit tests in test_dictconfig.py, at: + +http://bitbucket.org/vinay.sajip/dictconfig + +This incorporates all features other than the socket listener change. + + References ========== From python-checkins at python.org Wed Nov 25 23:59:37 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 25 Nov 2009 22:59:37 -0000 Subject: [Python-checkins] r76529 - in python/trunk: Doc/library/datetime.rst Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: Author: antoine.pitrou Date: Wed Nov 25 23:59:36 2009 New Revision: 76529 Log: Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` method returning the total number of seconds in the duration. Patch by Brian Quinlan. Modified: python/trunk/Doc/library/datetime.rst python/trunk/Lib/test/test_datetime.py python/trunk/Misc/NEWS python/trunk/Modules/datetimemodule.c Modified: python/trunk/Doc/library/datetime.rst ============================================================================== --- python/trunk/Doc/library/datetime.rst (original) +++ python/trunk/Doc/library/datetime.rst Wed Nov 25 23:59:36 2009 @@ -269,12 +269,22 @@ efficient pickling, and in Boolean contexts, a :class:`timedelta` object is considered to be true if and only if it isn't equal to ``timedelta(0)``. +Instance methods: + +.. method:: timedelta.total_seconds() + + Return the total number of seconds contained in the duration. Equivalent to + ``td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600``. + + Example usage: >>> from datetime import timedelta >>> year = timedelta(days=365) >>> another_year = timedelta(weeks=40, days=84, hours=23, ... minutes=50, seconds=600) # adds up to 365 days + >>> year.total_seconds() + 31536000.0 >>> year == another_year True >>> ten_years = 10 * year Modified: python/trunk/Lib/test/test_datetime.py ============================================================================== --- python/trunk/Lib/test/test_datetime.py (original) +++ python/trunk/Lib/test/test_datetime.py Wed Nov 25 23:59:36 2009 @@ -266,6 +266,13 @@ self.assertEqual(td.seconds, seconds) self.assertEqual(td.microseconds, us) + def test_total_seconds(self): + td = timedelta(days=365) + self.assertEqual(td.total_seconds(), 31536000.0) + for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]: + td = timedelta(seconds=total_seconds) + self.assertEqual(td.total_seconds(), total_seconds) + def test_carries(self): t1 = timedelta(days=100, weeks=-7, Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Nov 25 23:59:36 2009 @@ -483,6 +483,10 @@ Library ------- +- Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` + method returning the total number of seconds in the duration. Patch by + Brian Quinlan. + - Issue #6615: logging: Used weakrefs in internal handler list. - Issue #1488943: difflib.Differ() doesn't always add hints for tab characters Modified: python/trunk/Modules/datetimemodule.c ============================================================================== --- python/trunk/Modules/datetimemodule.c (original) +++ python/trunk/Modules/datetimemodule.c Wed Nov 25 23:59:36 2009 @@ -2089,6 +2089,14 @@ } static PyObject * +delta_total_seconds(PyObject *self) +{ + return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 + + GET_TD_SECONDS(self) + + GET_TD_DAYS(self) * 24.0 * 3600.0); +} + +static PyObject * delta_reduce(PyDateTime_Delta* self) { return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); @@ -2110,7 +2118,10 @@ }; static PyMethodDef delta_methods[] = { - {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, + {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS, + PyDoc_STR("Total seconds in the duration.")}, + + {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, {NULL, NULL}, From python-checkins at python.org Thu Nov 26 00:02:32 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 25 Nov 2009 23:02:32 -0000 Subject: [Python-checkins] r76530 - in python/branches/py3k: Doc/library/datetime.rst Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: Author: antoine.pitrou Date: Thu Nov 26 00:02:32 2009 New Revision: 76530 Log: Merged revisions 76529 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76529 | antoine.pitrou | 2009-11-25 23:59:36 +0100 (mer., 25 nov. 2009) | 4 lines Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` method returning the total number of seconds in the duration. Patch by Brian Quinlan. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/datetime.rst python/branches/py3k/Lib/test/test_datetime.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/datetimemodule.c Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Thu Nov 26 00:02:32 2009 @@ -267,12 +267,24 @@ efficient pickling, and in Boolean contexts, a :class:`timedelta` object is considered to be true if and only if it isn't equal to ``timedelta(0)``. +Instance methods: + +.. method:: timedelta.total_seconds() + + Return the total number of seconds contained in the duration. Equivalent to + ``td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600``. + + .. versionadded:: 3.2 + + Example usage: >>> from datetime import timedelta >>> year = timedelta(days=365) >>> another_year = timedelta(weeks=40, days=84, hours=23, ... minutes=50, seconds=600) # adds up to 365 days + >>> year.total_seconds() + 31536000.0 >>> year == another_year True >>> ten_years = 10 * year Modified: python/branches/py3k/Lib/test/test_datetime.py ============================================================================== --- python/branches/py3k/Lib/test/test_datetime.py (original) +++ python/branches/py3k/Lib/test/test_datetime.py Thu Nov 26 00:02:32 2009 @@ -261,6 +261,13 @@ self.assertEqual(td.seconds, seconds) self.assertEqual(td.microseconds, us) + def test_total_seconds(self): + td = timedelta(days=365) + self.assertEqual(td.total_seconds(), 31536000.0) + for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]: + td = timedelta(seconds=total_seconds) + self.assertEqual(td.total_seconds(), total_seconds) + def test_carries(self): t1 = timedelta(days=100, weeks=-7, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Nov 26 00:02:32 2009 @@ -140,6 +140,10 @@ Library ------- +- Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` + method returning the total number of seconds in the duration. Patch by + Brian Quinlan. + - Issue #7133: SSL objects now support the new buffer API. - Issue #1488943: difflib.Differ() doesn't always add hints for tab characters Modified: python/branches/py3k/Modules/datetimemodule.c ============================================================================== --- python/branches/py3k/Modules/datetimemodule.c (original) +++ python/branches/py3k/Modules/datetimemodule.c Thu Nov 26 00:02:32 2009 @@ -2063,6 +2063,14 @@ } static PyObject * +delta_total_seconds(PyObject *self) +{ + return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 + + GET_TD_SECONDS(self) + + GET_TD_DAYS(self) * 24.0 * 3600.0); +} + +static PyObject * delta_reduce(PyDateTime_Delta* self) { return Py_BuildValue("ON", Py_TYPE(self), delta_getstate(self)); @@ -2084,7 +2092,10 @@ }; static PyMethodDef delta_methods[] = { - {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, + {"total_seconds", (PyCFunction)delta_total_seconds, METH_NOARGS, + PyDoc_STR("Total seconds in the duration.")}, + + {"__reduce__", (PyCFunction)delta_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, {NULL, NULL}, From python-checkins at python.org Thu Nov 26 00:03:23 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 25 Nov 2009 23:03:23 -0000 Subject: [Python-checkins] r76531 - python/trunk/Doc/library/datetime.rst Message-ID: Author: antoine.pitrou Date: Thu Nov 26 00:03:22 2009 New Revision: 76531 Log: Forgot to add a `versionadded` tag Modified: python/trunk/Doc/library/datetime.rst Modified: python/trunk/Doc/library/datetime.rst ============================================================================== --- python/trunk/Doc/library/datetime.rst (original) +++ python/trunk/Doc/library/datetime.rst Thu Nov 26 00:03:22 2009 @@ -276,6 +276,8 @@ Return the total number of seconds contained in the duration. Equivalent to ``td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600``. + .. versionadded:: 2.7 + Example usage: From python-checkins at python.org Thu Nov 26 00:03:49 2009 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 25 Nov 2009 23:03:49 -0000 Subject: [Python-checkins] r76532 - python/branches/py3k Message-ID: Author: antoine.pitrou Date: Thu Nov 26 00:03:48 2009 New Revision: 76532 Log: Blocked revisions 76531 via svnmerge ........ r76531 | antoine.pitrou | 2009-11-26 00:03:22 +0100 (jeu., 26 nov. 2009) | 3 lines Forgot to add a `versionadded` tag ........ Modified: python/branches/py3k/ (props changed) From solipsis at pitrou.net Thu Nov 26 00:48:26 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 26 Nov 2009 00:48:26 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76525): sum=14 Message-ID: <20091125234826.10BC717722@ns6635.ovh.net> py3k results for svn r76525 (hg cset 8b343781405c) -------------------------------------------------- test_urllib leaked [8, 2, 4] references, sum=14 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/refloggqpzfA', '-x', 'test_httpservers'] From python-checkins at python.org Thu Nov 26 08:57:39 2009 From: python-checkins at python.org (vinay.sajip) Date: Thu, 26 Nov 2009 07:57:39 -0000 Subject: [Python-checkins] r76533 - peps/trunk/pep-0391.txt Message-ID: Author: vinay.sajip Date: Thu Nov 26 08:57:39 2009 New Revision: 76533 Log: Updated to incorporate suggestions made by Terry Reedy. Modified: peps/trunk/pep-0391.txt Modified: peps/trunk/pep-0391.txt ============================================================================== --- peps/trunk/pep-0391.txt (original) +++ peps/trunk/pep-0391.txt Thu Nov 26 08:57:39 2009 @@ -51,11 +51,11 @@ Although the standard library does not contain YAML support at present, support for both JSON and YAML can be provided in a common way because both of these serialization formats allow deserialization -of Python dictionaries. +to Python dictionaries. By providing a way to configure logging by passing the configuration in a dictionary, logging will be easier to configure not only for -users of JSON and/or YAML, but also for users of bespoke configuration +users of JSON and/or YAML, but also for users of custom configuration methods, by providing a common format in which to describe the desired configuration. @@ -90,12 +90,11 @@ API --- -The logging.config module will have the following additions: +The logging.config module will have the following addition: * A function, called ``dictConfig()``, which takes a single argument - - the dictionary holding the configuration. Nothing will be - returned, though exceptions will be raised if there are errors while - processing the dictionary. + - the dictionary holding the configuration. Exceptions will be + raised if there are errors while processing the dictionary. It will be possible to customize this API - see the section on `API Customization`_. `Incremental configuration`_ is covered in its own @@ -117,7 +116,7 @@ handlers, formatters, filters - which are connected to each other in an object graph. Thus, the schema needs to represent connections between the objects. For example, say that, once configured, a -particular logger has an attached to it a particular handler. For the +particular logger has attached to it a particular handler. For the purposes of this discussion, we can say that the logger represents the source, and the handler the destination, of a connection between the two. Of course in the configured objects this is represented by the @@ -183,8 +182,9 @@ flexibility for user-defined object instantiation, the user will need to provide a 'factory' - a callable which is called with a configuration dictionary and which returns the instantiated object. -This will be signalled by the factory being made available under the -special key ``'()'``. Here's a concrete example:: +This will be signalled by an absolute import path to the factory being +made available under the special key ``'()'``. Here's a concrete +example:: formatters: brief: @@ -232,10 +232,13 @@ and this contains the special key ``'()'``, which means that user-defined instantiation is wanted. In this case, the specified -factory callable will be located using normal import mechanisms and -called with the *remaining* items in the configuration sub-dictionary -as keyword arguments. In the above example, the formatter with id -``custom`` will be assumed to be returned by the call:: +factory callable will be used. If it is an actual callable it will be +used directly - otherwise, if you specify a string (as in the example) +the actual callable will be located using normal import mechanisms. +The callable will be called with the *remaining* items in the +configuration sub-dictionary as keyword arguments. In the above +example, the formatter with id ``custom`` will be assumed to be +returned by the call:: my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42) @@ -618,7 +621,7 @@ follows: when a configuration message is received, an attempt will be made to deserialize to a dictionary using the json module. If this step fails, the message will be assumed to be in the fileConfig format -and processed as before. If serialization is successful, then +and processed as before. If deserialization is successful, then ``dictConfig()`` will be called to process the resulting dictionary. From python-checkins at python.org Thu Nov 26 09:42:05 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 26 Nov 2009 08:42:05 -0000 Subject: [Python-checkins] r76534 - python/trunk/Tools/buildbot/buildmsi.bat Message-ID: Author: martin.v.loewis Date: Thu Nov 26 09:42:05 2009 New Revision: 76534 Log: Fix typo. Modified: python/trunk/Tools/buildbot/buildmsi.bat Modified: python/trunk/Tools/buildbot/buildmsi.bat ============================================================================== --- python/trunk/Tools/buildbot/buildmsi.bat (original) +++ python/trunk/Tools/buildbot/buildmsi.bat Thu Nov 26 09:42:05 2009 @@ -11,7 +11,7 @@ bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp' "%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\python26a3.hhp - at rem buold the MSI file + at rem build the MSI file cd PC nmake /f icons.mak cd ..\Tools\msi From nnorwitz at gmail.com Thu Nov 26 10:32:31 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 26 Nov 2009 04:32:31 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091126093231.GA16275@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 19, in test_local_refs self._local_refs(20) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 18 != 19 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881217 refs] From nnorwitz at gmail.com Thu Nov 26 11:59:56 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 26 Nov 2009 05:59:56 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091126105956.GA15838@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 0, 339] references, sum=339 Less important issues: ---------------------- From python-checkins at python.org Thu Nov 26 13:36:30 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 26 Nov 2009 12:36:30 -0000 Subject: [Python-checkins] r76535 - in python/trunk/Lib/test: test_multibytecodec_support.py test_normalization.py Message-ID: Author: antoine.pitrou Date: Thu Nov 26 13:36:30 2009 New Revision: 76535 Log: When open_urlresource() fails, HTTPException is another possible error Modified: python/trunk/Lib/test/test_multibytecodec_support.py python/trunk/Lib/test/test_normalization.py Modified: python/trunk/Lib/test/test_multibytecodec_support.py ============================================================================== --- python/trunk/Lib/test/test_multibytecodec_support.py (original) +++ python/trunk/Lib/test/test_multibytecodec_support.py Thu Nov 26 13:36:30 2009 @@ -6,6 +6,7 @@ import sys, codecs import unittest, re +from httplib import HTTPException from test import test_support from StringIO import StringIO @@ -268,7 +269,7 @@ unittest.TestCase.__init__(self, *args, **kw) try: self.open_mapping_file() # test it to report the error early - except IOError: + except (IOError, HTTPException): self.skipTest("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): Modified: python/trunk/Lib/test/test_normalization.py ============================================================================== --- python/trunk/Lib/test/test_normalization.py (original) +++ python/trunk/Lib/test/test_normalization.py Thu Nov 26 13:36:30 2009 @@ -1,6 +1,7 @@ from test.test_support import run_unittest, open_urlresource import unittest +from httplib import HTTPException import sys import os from unicodedata import normalize, unidata_version @@ -43,7 +44,7 @@ # Hit the exception early try: open_urlresource(TESTDATAURL) - except IOError: + except (IOError, HTTPException): self.skipTest("Could not retrieve " + TESTDATAURL) for line in open_urlresource(TESTDATAURL): if '#' in line: From python-checkins at python.org Thu Nov 26 13:38:24 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 26 Nov 2009 12:38:24 -0000 Subject: [Python-checkins] r76536 - in python/branches/py3k: Lib/test/test_multibytecodec_support.py Lib/test/test_normalization.py Message-ID: Author: antoine.pitrou Date: Thu Nov 26 13:38:23 2009 New Revision: 76536 Log: Merged revisions 76535 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76535 | antoine.pitrou | 2009-11-26 13:36:30 +0100 (jeu., 26 nov. 2009) | 3 lines When open_urlresource() fails, HTTPException is another possible error ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_multibytecodec_support.py python/branches/py3k/Lib/test/test_normalization.py Modified: python/branches/py3k/Lib/test/test_multibytecodec_support.py ============================================================================== --- python/branches/py3k/Lib/test/test_multibytecodec_support.py (original) +++ python/branches/py3k/Lib/test/test_multibytecodec_support.py Thu Nov 26 13:38:23 2009 @@ -6,6 +6,7 @@ import sys, codecs import unittest, re +from http.client import HTTPException from test import support from io import BytesIO @@ -278,7 +279,7 @@ unittest.TestCase.__init__(self, *args, **kw) try: self.open_mapping_file() # test it to report the error early - except IOError: + except (IOError, HTTPException): self.skipTest("Could not retrieve "+self.mapfileurl) def open_mapping_file(self): Modified: python/branches/py3k/Lib/test/test_normalization.py ============================================================================== --- python/branches/py3k/Lib/test/test_normalization.py (original) +++ python/branches/py3k/Lib/test/test_normalization.py Thu Nov 26 13:38:23 2009 @@ -1,6 +1,7 @@ from test.support import run_unittest, open_urlresource import unittest +from http.client import HTTPException import sys import os from unicodedata import normalize, unidata_version @@ -45,7 +46,7 @@ # Hit the exception early try: open_urlresource(TESTDATAURL, encoding="utf-8") - except IOError: + except (IOError, HTTPException): self.skipTest("Could not retrieve " + TESTDATAURL) for line in open_urlresource(TESTDATAURL, encoding="utf-8"): if '#' in line: From python-checkins at python.org Thu Nov 26 21:48:26 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 26 Nov 2009 20:48:26 -0000 Subject: [Python-checkins] r76538 - python/trunk/Doc/library/functions.rst Message-ID: Author: georg.brandl Date: Thu Nov 26 21:48:25 2009 New Revision: 76538 Log: #7400: typo. Modified: python/trunk/Doc/library/functions.rst Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Thu Nov 26 21:48:25 2009 @@ -1097,7 +1097,7 @@ .. function:: set([iterable]) :noindex: - Return a new set, optionally with elements are taken from *iterable*. + Return a new set, optionally with elements taken from *iterable*. The set type is described in :ref:`types-set`. For other containers see the built in :class:`dict`, :class:`list`, and From nnorwitz at gmail.com Thu Nov 26 23:51:51 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 26 Nov 2009 17:51:51 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091126225151.GA28009@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [81, 339, 0] references, sum=420 Less important issues: ---------------------- test_zipimport_support leaked [25, 0, -25] references, sum=0 From solipsis at pitrou.net Fri Nov 27 00:47:10 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 27 Nov 2009 00:47:10 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76536): sum=8 Message-ID: <20091126234710.DFE6D17714@ns6635.ovh.net> py3k results for svn r76536 (hg cset ffee262c4dba) -------------------------------------------------- test_urllib leaked [6, 0, 2] references, sum=8 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogxqckKZ', '-x', 'test_httpservers'] From nnorwitz at gmail.com Fri Nov 27 10:24:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 27 Nov 2009 04:24:43 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091127092443.GA26134@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881222 refs] From python-checkins at python.org Fri Nov 27 12:58:05 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 27 Nov 2009 11:58:05 -0000 Subject: [Python-checkins] r76545 - in tracker/roundup-src: CHANGES.txt demo.py doc/FAQ.txt doc/acknowledgements.txt doc/announcement.txt doc/developers.txt doc/features.txt doc/installation.txt doc/upgrading.txt doc/xmlrpc.txt locale/de.mo locale/de.po locale/fr.po roundup/__init__.py roundup/actions.py roundup/admin.py roundup/backends/__init__.py roundup/backends/back_postgresql.py roundup/backends/back_sqlite.py roundup/backends/indexer_common.py roundup/backends/indexer_dbm.py roundup/backends/indexer_rdbms.py roundup/backends/indexer_xapian.py roundup/cgi/PageTemplates/Expressions.py roundup/cgi/actions.py roundup/cgi/apache.py roundup/cgi/cgitb.py roundup/cgi/client.py roundup/cgi/form_parser.py roundup/cgi/templating.py roundup/configuration.py roundup/instance.py roundup/mailer.py roundup/mailgw.py roundup/roundupdb.py roundup/scripts/roundup_mailgw.py roundup/scripts/roundup_server.py roundup/xmlrpc.py setup.py share/roundup/templates/classic/html/_generic.item.html share/roundup/templates/classic/html/page.html share/roundup/templates/classic/html/style.css share/roundup/templates/classic/schema.py share/roundup/templates/minimal/html/_generic.item.html share/roundup/templates/minimal/html/page.html share/roundup/templates/minimal/html/user.item.html share/roundup/templates/minimal/schema.py test/db_test_base.py test/test_anypy_hashlib.py test/test_indexer.py test/test_mailgw.py test/test_xmlrpc.py Message-ID: Author: martin.v.loewis Date: Fri Nov 27 12:58:04 2009 New Revision: 76545 Log: Upgrade to 1.4.10, taken from http://pypi.python.org/pypi/roundup/1.4.10. Added: tracker/roundup-src/locale/de.mo (contents, props changed) Modified: tracker/roundup-src/CHANGES.txt tracker/roundup-src/demo.py tracker/roundup-src/doc/FAQ.txt tracker/roundup-src/doc/acknowledgements.txt tracker/roundup-src/doc/announcement.txt tracker/roundup-src/doc/developers.txt tracker/roundup-src/doc/features.txt tracker/roundup-src/doc/installation.txt tracker/roundup-src/doc/upgrading.txt tracker/roundup-src/doc/xmlrpc.txt tracker/roundup-src/locale/de.po tracker/roundup-src/locale/fr.po tracker/roundup-src/roundup/__init__.py tracker/roundup-src/roundup/actions.py tracker/roundup-src/roundup/admin.py tracker/roundup-src/roundup/backends/__init__.py tracker/roundup-src/roundup/backends/back_postgresql.py tracker/roundup-src/roundup/backends/back_sqlite.py tracker/roundup-src/roundup/backends/indexer_common.py tracker/roundup-src/roundup/backends/indexer_dbm.py tracker/roundup-src/roundup/backends/indexer_rdbms.py tracker/roundup-src/roundup/backends/indexer_xapian.py tracker/roundup-src/roundup/cgi/PageTemplates/Expressions.py tracker/roundup-src/roundup/cgi/actions.py tracker/roundup-src/roundup/cgi/apache.py tracker/roundup-src/roundup/cgi/cgitb.py tracker/roundup-src/roundup/cgi/client.py tracker/roundup-src/roundup/cgi/form_parser.py tracker/roundup-src/roundup/cgi/templating.py tracker/roundup-src/roundup/configuration.py tracker/roundup-src/roundup/instance.py tracker/roundup-src/roundup/mailer.py tracker/roundup-src/roundup/mailgw.py tracker/roundup-src/roundup/roundupdb.py tracker/roundup-src/roundup/scripts/roundup_mailgw.py tracker/roundup-src/roundup/scripts/roundup_server.py tracker/roundup-src/roundup/xmlrpc.py tracker/roundup-src/setup.py tracker/roundup-src/share/roundup/templates/classic/html/_generic.item.html tracker/roundup-src/share/roundup/templates/classic/html/page.html tracker/roundup-src/share/roundup/templates/classic/html/style.css tracker/roundup-src/share/roundup/templates/classic/schema.py tracker/roundup-src/share/roundup/templates/minimal/html/_generic.item.html tracker/roundup-src/share/roundup/templates/minimal/html/page.html tracker/roundup-src/share/roundup/templates/minimal/html/user.item.html tracker/roundup-src/share/roundup/templates/minimal/schema.py tracker/roundup-src/test/db_test_base.py tracker/roundup-src/test/test_anypy_hashlib.py tracker/roundup-src/test/test_indexer.py tracker/roundup-src/test/test_mailgw.py tracker/roundup-src/test/test_xmlrpc.py Modified: tracker/roundup-src/CHANGES.txt ============================================================================== --- tracker/roundup-src/CHANGES.txt (original) +++ tracker/roundup-src/CHANGES.txt Fri Nov 27 12:58:04 2009 @@ -1,12 +1,45 @@ This file contains the changes to the Roundup system over time. The entries are given with the most recent entry first. -2009-03-?? 1.4.9 (r??) +2009-10-09 1.4.10 (r4374) Fixes: +- Minor update of doc/developers.txt to point to the new resources + on www.roundup-tracker.org (Bernhard Reiter) +- Small CSS improvements regaring the search box (thanks Thomas Arendsan Hein) + (issue 2550589) +- Indexers behaviour made more consistent regarding length of indexed words + and stopwords (thanks Thomas Arendsen Hein, Bernhard Reiter)(issue 2550584) +- fixed typos in the installation instructions (thanks Thomas Arendsen Hein) + (issue 2550573) +- New config option csv_field_size: Pythons csv module (which is used + for export/import) has a new field size limit starting with python2.5. + We now issue a warning during export if the limit is too small and use + the csv_field_size configuration during import to set the limit for + the csv module. +- Small fix for CGI-handling of XMLRPC requests for python2.4, this + worked only for 2.5 and beyond due to a change in the xmlrpc interface + in python +- Document filter method of xmlrpc interface +- Fix interaction of SSL and XMLRPC, now XMLRPC works with SSL +2009-08-10 1.4.9 (r4346) + +Fixes: - fixed action taken in response to invalid GET request - fixed classic tracker template to submit POST requests when appropriate +- fix problems with french and german locale files (issue 2550546) +- Run each message of the mail-gateway in a separate transaction, + see http://thread.gmane.org/gmane.comp.bug-tracking.roundup.user/9500 +- fix problem with bounce-message if incoming mail has insufficient + privilege, e.g., user not existing (issue 2550534) +- fix construction of individual messages to nosy recipents with + attachments (issue 2550568) +- re-order sqlite imports to handle multiple installed versions (issue + 2550570) +- don't show entire history by default + (fixes http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=540629) +- remove use of string exception 2009-03-18 1.4.8 (r4209) Modified: tracker/roundup-src/demo.py ============================================================================== --- tracker/roundup-src/demo.py (original) +++ tracker/roundup-src/demo.py Fri Nov 27 12:58:04 2009 @@ -2,7 +2,6 @@ # # Copyright (c) 2003 Richard Jones (richard at mechanicalcat.net) # -# $Id: demo.py,v 1.26 2007-08-28 22:37:45 jpend Exp $ import errno import os @@ -10,6 +9,7 @@ import sys import urlparse from glob import glob +import getopt from roundup import configuration from roundup.scripts import roundup_server @@ -23,9 +23,10 @@ backend: database backend name template: - full path to the tracker template directory + tracker template """ + from roundup import init, instance, password, backends # set up the config for this tracker @@ -45,14 +46,15 @@ if module.db_exists(config): module.db_nuke(config) - init.install(home, template) + template_dir = os.path.join('share', 'roundup', 'templates', template) + init.install(home, template_dir) # don't have email flying around - os.remove(os.path.join(home, 'detectors', 'nosyreaction.py')) - try: - os.remove(os.path.join(home, 'detectors', 'nosyreaction.pyc')) - except os.error, error: - if error.errno != errno.ENOENT: - raise + nosyreaction = os.path.join(home, 'detectors', 'nosyreaction.py') + if os.path.exists(nosyreaction): + os.remove(nosyreaction) + nosyreaction += 'c' + if os.path.exists(nosyreaction): + os.remove(nosyreaction) init.write_select_db(home, backend) # figure basic params for server @@ -86,8 +88,13 @@ # add the "demo" user db = tracker.open('admin') - db.user.create(username='demo', password=password.Password('demo'), - realname='Demo User', roles='User') + # FIXME: Move tracker-specific demo initialization into the tracker templates. + if (template == 'minimal'): + db.user.create(username='demo', password=password.Password('demo'), + roles='User') + else: + db.user.create(username='demo', password=password.Password('demo'), + realname='Demo User', roles='User') db.commit() db.close() @@ -116,21 +123,59 @@ sys.argv = sys.argv[:1] + ['-p', str(port), 'demo=' + home] roundup_server.run(success_message=success_message) -def demo_main(): + +def usage(msg = ''): + + if msg: print msg + print 'Usage: %s [options] [nuke]'%sys.argv[0] + print """ +Options: + -h -- print this help message + -t template -- specify the tracker template to use + -b backend -- specify the database backend to use +""" + + +def main(): """Run a demo server for users to play with for instant gratification. Sets up the web service on localhost. Disables nosy lists. """ + + try: + opts, args = getopt.getopt(sys.argv[1:], 't:b:h') + except getopt.GetoptError, e: + usage(str(e)) + return 1 + home = os.path.abspath('demo') - if not os.path.exists(home) or (sys.argv[-1] == 'nuke'): - if len(sys.argv) > 2: - backend = sys.argv[-2] - else: - backend = 'anydbm' - install_demo(home, backend, os.path.join('share', 'roundup', 'templates', 'classic')) + nuke = args and args[0] == 'nuke' + if not os.path.exists(home) or nuke: + backend = 'anydbm' + template = 'classic' + for opt, arg in opts: + if opt == '-h': + usage() + return 0 + elif opt == '-t': + template = arg + elif opt == '-b': + backend = arg + if (len(args) > 1 or + (len(args) == 1 and args[0] != 'nuke')): + usage() + return 1 + + install_demo(home, backend, template) + elif opts: + print "Error: Arguments are not allowed when running an existing demo." + print " Use the 'nuke' command to start over." + sys.exit(1) + run_demo(home) + if __name__ == '__main__': - demo_main() + sys.exit(main()) # vim: set filetype=python sts=4 sw=4 et si : Modified: tracker/roundup-src/doc/FAQ.txt ============================================================================== --- tracker/roundup-src/doc/FAQ.txt (original) +++ tracker/roundup-src/doc/FAQ.txt Fri Nov 27 12:58:04 2009 @@ -96,8 +96,18 @@ How do I run Roundup through SSL (HTTPS)? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You should proxy through apache and use its SSL service. See the previous -question on how to proxy through apache. +The preferred way of using SSL is to proxy through apache and use its +SSL service. See the previous question on how to proxy through apache. + +The standalone roundup-server now also has SSL support which is still +considered experimental. For details refer to the documentation of +roundup server, in particular to the generated configuration file +generated with :: + + roundup-server --save-config + +that describes the needed option in detail. With the standalone server +now XMLRPC over SSL works, too. Roundup runs very slowly on my XP machine when accessed from the Internet @@ -107,7 +117,7 @@ performing the request. You can turn off the resolution of the names when it's so slow like this. To do so, edit the module roundup/scripts/roundup_server.py around line 77 to add the following -to the RoundupRequestHandler class: +to the RoundupRequestHandler class:: def address_string(self): return self.client_address[0] @@ -133,7 +143,8 @@ But I just want a select/option list for .... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Really easy... edit ``html/issue.item``. For 'nosy', change line 53 from:: +Really easy... edit ``html/issue.item.html``. For ``nosy``, change the line +(around line 69) from:: @@ -141,11 +152,7 @@ -For 'assigned to', change line 61 from:: - - assignedto menu - -to:: +For ``assigned to``, this is already done around line 77:: assignedto menu @@ -156,7 +163,7 @@ Thats a little harder (but only a little ;^) -Again, edit ``html/issue.item``. For nosy, change line 53 from: +Again, edit ``html/issue.item``. For nosy, change line (around line 69) from:: Modified: tracker/roundup-src/doc/acknowledgements.txt ============================================================================== --- tracker/roundup-src/doc/acknowledgements.txt (original) +++ tracker/roundup-src/doc/acknowledgements.txt Fri Nov 27 12:58:04 2009 @@ -51,7 +51,6 @@ Engelbert Gruber, Bruce Guenter, Tam??s Gul??csi, -Thomas Arendsen Hein, Juergen Hermann, Tobias Herp, Uwe Hoffmann, @@ -120,6 +119,7 @@ Jon C. Thomason Mike Thompson, Michael Twomey, +Joseph E. Trent, Karl Ulbrich, Martin Uzak, Darryl VanDorp, Modified: tracker/roundup-src/doc/announcement.txt ============================================================================== --- tracker/roundup-src/doc/announcement.txt (original) +++ tracker/roundup-src/doc/announcement.txt Fri Nov 27 12:58:04 2009 @@ -1,30 +1,28 @@ -I'm proud to release version 1.4.8 of Roundup. +I'm proud to release version 1.4.10 of Roundup which fixes some bugs: -This release fixes some regressions: - -- bug introduced into hyperdb filter (issue 2550505) -- bug introduced into CVS export and view (issue 2550529) -- bugs introduced in the migration to the email package (issue 2550531) - -And adds a couple of other fixes: - -- handle bogus pagination values (issue 2550530) -- fix TLS handling with some SMTP servers (issues 2484879 and 1912923) - - -Though some new features made it in also: - -- Provide a "no selection" option in web interface selection widgets -- Debug logging now uses the logging module rather than print -- Allow CGI frontend to serve XMLRPC requests. -- Added XMLRPC actions, as well as bridging CGI actions to XMLRPC actions. -- Optimized large file serving via mod_python / sendfile(). -- Support resuming downloads for (large) files. +- Minor update of doc/developers.txt to point to the new resources + on www.roundup-tracker.org (Bernhard Reiter) +- Small CSS improvements regaring the search box (thanks Thomas Arendsan Hein) + (issue 2550589) +- Indexers behaviour made more consistent regarding length of indexed words + and stopwords (thanks Thomas Arendsen Hein, Bernhard Reiter)(issue 2550584) +- fixed typos in the installation instructions (thanks Thomas Arendsen Hein) + (issue 2550573) +- New config option csv_field_size: Pythons csv module (which is used + for export/import) has a new field size limit starting with python2.5. + We now issue a warning during export if the limit is too small and use + the csv_field_size configuration during import to set the limit for + the csv module. +- Small fix for CGI-handling of XMLRPC requests for python2.4, this + worked only for 2.5 and beyond due to a change in the xmlrpc interface + in python +- Document filter method of xmlrpc interface +- Fix interaction of SSL and XMLRPC, now XMLRPC works with SSL If you're upgrading from an older version of Roundup you *must* follow the "Software Upgrade" guidelines given in the maintenance documentation. -Roundup requires python 2.3 or later for correct operation. +Roundup requires python 2.3 or later (but not 3+) for correct operation. To give Roundup a try, just download (see below), unpack and run:: @@ -58,9 +56,9 @@ The system will facilitate communication among the participants by managing discussions and notifying interested parties when issues are edited. One of the major design goals for Roundup that it be simple to get going. Roundup -is therefore usable "out of the box" with any python 2.3+ installation. It -doesn't even need to be "installed" to be operational, though a -disutils-based install script is provided. +is therefore usable "out of the box" with any python 2.3+ (but not 3+) +installation. It doesn't even need to be "installed" to be operational, +though an install script is provided. It comes with two issue tracker templates (a classic bug/feature tracker and a minimal skeleton) and four database back-ends (anydbm, sqlite, mysql Modified: tracker/roundup-src/doc/developers.txt ============================================================================== --- tracker/roundup-src/doc/developers.txt (original) +++ tracker/roundup-src/doc/developers.txt Fri Nov 27 12:58:04 2009 @@ -19,64 +19,30 @@ - roundup-dev mailing list at http://lists.sourceforge.net/mailman/listinfo/roundup-devel -- Sourceforge's issue trackers at - https://sourceforge.net/tracker/?group_id=31577 +- The issue tracker running at + http://issues.roundup-tracker.org/ + +Website, wiki, issue tracker +---------------------------- + +1. Log into ,roundup at shell.sourceforge.net +2. cd /home/groups/r/ro/roundup +3. follow instructions in README.txt + Small Changes ------------- -Most small changes can be submitted through the `feature tracker`_, with +Most small changes can be submitted through the issue tracker, with patches attached that give context diffs of the affected source. -CVS Access +SVN Access ---------- -To get CVS access, contact richard at users.sourceforge.net. - -CVS stuff: - -1. to tag a release (eg. the pre-release of 0.5.0):: - - cvs tag release-0-5-0-pr1 - -1. to make a branch (eg. branching for code freeze/release):: - - cvs co -d maint-0-5 -r release-0-5-0-pr1 roundup - cd maint-0-5 - cvs tag -b maint-0-5 - -2. to check out a branch (eg. the maintenance branch for 0.5.x):: - - cvs co -d maint-0-5 -r maint-0-5 - -3. to merge changes from the maintenance branch to the trunk, in the - directory containing the HEAD checkout:: - - cvs up -j maint-0-5 - - though this is highly discouraged, as it generally creates a whole swag - of conflicts :( - -Standard tag names: - -*release-maj-min-patch[-sub]* - Release of the major.minor.patch release, possibly a beta or pre-release, - in which case *sub* will be one of "b*N*" or "pr*N*". -*maint-maj-min* - Maintenance branch for the major.minor release. Patch releases are tagged in - this branch. - -Typically, release happen like this: +See http://www.roundup-tracker.org/code.html. +For all other questions ask on the development mailinglist. -1. work progresses in the HEAD branch until milestones are met, -2. a series of beta releases are tagged in the HEAD until the code is - stable enough to freeze, -3. the pre-release is tagged in the HEAD, with the resultant code branched - to the maintenance branch for that release, -4. bugs in the release are patched in the maintenance branch, and the final - and patch releases are tagged there, and -5. further major work happens in the HEAD. Project Rules ------------- @@ -86,7 +52,7 @@ - 80 column width code - 4-space indentations -- All modules must have a CVS Id line near the top +- All modules must have an Id line near the top Other project rules: @@ -94,7 +60,7 @@ where there's missing documentation) and changes to tracker configuration must be logged in the upgrading document. - subscribe to roundup-checkins to receive checkin notifications from the - other developers with CVS access + other developers with write access to the source-code repository. - discuss any changes with the other developers on roundup-dev. If nothing else, this makes sure there's no rude shocks - write unit tests for changes you make (where possible), and ensure that @@ -144,8 +110,8 @@ message translators. 4. Translated Message Files are compiled into binary form (_`MO` files) - and stored in ``locale`` directory (but not kept in the `Roundup - CVS`_ repository, as they may be easily made from PO files). + and stored in ``locale`` directory (but not kept in the source code + repository, as they may be easily made from PO files). See `Compiling Message Catalogs`_ section. 5. Roundup installer creates runtime locale structure on the file @@ -346,8 +312,9 @@ This means that you need both `GNU gettext`_ tools and `PO utilities`_ to build the Message Template File yourself. -Latest Message Template File is kept in `Roundup CVS`_ and distributed -with `Roundup Source`_. If you wish to rebuild the template yourself, +Latest Message Template File is kept in the source code repository +and distributed with `Roundup Source`_. +If you wish to rebuild the template yourself, make sure that you have both ``xpot`` and ``xgettext`` installed and just run ``gmake`` (or ``make``, if you are on a `GNU`_ system like `linux`_ or `cygwin`_) in the ``locale`` directory. @@ -451,7 +418,6 @@ http://vim.sourceforge.net/scripts/script.php?script_id=695 .. _PO utilities: http://po-utils.progiciels-bpi.ca/ .. _poEdit: http://poedit.sourceforge.net/ -.. _Roundup CVS: http://sourceforge.net/cvs/?group_id=31577 .. _Roundup Source: .. _Roundup source distribution: .. _Roundup binary distribution: @@ -464,5 +430,4 @@ http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TALES%20Specification%201.3 .. _vim: http://www.vim.org/ .. _ZPTInternationalizationSupport: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/ZPTInternationalizationSupport -.. _feature tracker: http://sourceforge.net/tracker/?group_id=31577&atid=402791 Modified: tracker/roundup-src/doc/features.txt ============================================================================== --- tracker/roundup-src/doc/features.txt (original) +++ tracker/roundup-src/doc/features.txt Fri Nov 27 12:58:04 2009 @@ -12,7 +12,7 @@ - two templates included in the distribution for you to base your tracker on - play with the demo, customise it and then use *it* as the template for your production tracker - - requires *no* additional support software - python (2.3+) is + - requires *no* additional support software - python (2.3+ but not 3+) is enough to get you going - easy to set up higher-performance storage backends like sqlite_, mysql_ and postgresql_ Modified: tracker/roundup-src/doc/installation.txt ============================================================================== --- tracker/roundup-src/doc/installation.txt (original) +++ tracker/roundup-src/doc/installation.txt Fri Nov 27 12:58:04 2009 @@ -30,8 +30,8 @@ Prerequisites ============= -Roundup requires Python 2.3 or newer with a functioning anydbm -module. Download the latest version from http://www.python.org/. +Roundup requires Python 2.3 or newer (but not Python 3) with a functioning +anydbm module. Download the latest version from http://www.python.org/. It is highly recommended that users install the latest patch version of python as these contain many fixes to serious bugs. @@ -441,14 +441,14 @@ export LD_PRELOAD Next, you have to add Roundup trackers configuration to apache config. -Roundup apache interface uses two options specified with ``PythonOption`` -directives: +Roundup apache interface uses the following options specified with +``PythonOption`` directives: TrackerHome: defines the tracker home directory - the directory that was specified when you did ``roundup-admin init``. This option is required. - TrackerLaguage: + TrackerLanguage: defines web user interface language. mod_python applications do not receive OS environment variables in the same way as command-line programs, so the language cannot be selected by setting commonly @@ -482,7 +482,7 @@ interface (default). Static files from ``html`` directory are served by apache itself - this -is quickier and generally more robust than doing that from python. +is quicker and generally more robust than doing that from python. Everything else is aliased to dummy (non-existing) ``py`` file, which is handled by mod_python and our roundup module. Modified: tracker/roundup-src/doc/upgrading.txt ============================================================================== --- tracker/roundup-src/doc/upgrading.txt (original) +++ tracker/roundup-src/doc/upgrading.txt Fri Nov 27 12:58:04 2009 @@ -16,6 +16,18 @@ Migrating from 1.4.x to 1.4.9 ============================= +Customized MailGW Class +----------------------- + +If you have customized the MailGW class in your tracker: The new MailGW +class opens the database for each message in the method handle_message +(instance.open) instead of passing the opened database as a parameter to +the MailGW constructor. The old handle_message has been renamed to +_handle_message. The new method opens the database and wraps the call to +the old method into a try/finally. + +Your customized MailGW class needs to mirror this behavior. + Fix the "remove" button in issue files and messages lists --------------------------------------------------------- Modified: tracker/roundup-src/doc/xmlrpc.txt ============================================================================== --- tracker/roundup-src/doc/xmlrpc.txt (original) +++ tracker/roundup-src/doc/xmlrpc.txt Fri Nov 27 12:58:04 2009 @@ -64,6 +64,13 @@ Set the values of an existing item in the tracker as specified by ``designator``. The new values are specified in ``arg_1`` through ``arg_N``. The arguments are name=value pairs (e.g. ``status='3'``). + +filter arguments: *classname, list or None, attributes* + + list can be None (requires ``allow_none=True`` when + instantiating the ServerProxy) to indicate search for all values, + or a list of ids. The attributes are given as a dictionary of + name value pairs to search for. ======= ==================================================================== sample python client @@ -71,7 +78,7 @@ :: >>> import xmlrpclib - >>> roundup_server = xmlrpclib.ServerProxy('http://username:password at localhost:8000') + >>> roundup_server = xmlrpclib.ServerProxy('http://username:password at localhost:8000', allow_none=True) >>> roundup_server.list('user') ['admin', 'anonymous', 'demo'] >>> roundup_server.list('issue', 'id') @@ -85,4 +92,11 @@ {'status' : '3' } >>> roundup_server.create('issue', "title='another bug'", "status=2") '2' - + >>> roundup_server.filter('user',None,{'username':'adm'}) + ['1'] + >>> roundup_server.filter('user',['1','2'],{'username':'adm'}) + ['1'] + >>> roundup_server.filter('user',['2'],{'username':'adm'}) + [] + >>> roundup_server.filter('user',[],{'username':'adm'}) + [] Added: tracker/roundup-src/locale/de.mo ============================================================================== Binary file. No diff available. Modified: tracker/roundup-src/locale/de.po ============================================================================== --- tracker/roundup-src/locale/de.po (original) +++ tracker/roundup-src/locale/de.po Fri Nov 27 12:58:04 2009 @@ -10,7 +10,7 @@ "Project-Id-Version: Roundup 1.4.6\n" "Report-Msgid-Bugs-To: roundup-devel at lists.sourceforge.net\n" "POT-Creation-Date: 2009-03-12 11:58+0200\n" -"PO-Revision-Date: 2009-03-12 18:05Westeurop?ische Normalzeit\n" +"PO-Revision-Date: 2009-03-12 18:05+0200\n" "Last-Translator: Tobias Herp \n" "Language-Team: German Translators \n" "MIME-Version: 1.0\n" Modified: tracker/roundup-src/locale/fr.po ============================================================================== --- tracker/roundup-src/locale/fr.po (original) +++ tracker/roundup-src/locale/fr.po Fri Nov 27 12:58:04 2009 @@ -16,7 +16,7 @@ "Last-Translator: St?phane Raimbault \n" "Language-Team: GNOME French Team \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n" Modified: tracker/roundup-src/roundup/__init__.py ============================================================================== --- tracker/roundup-src/roundup/__init__.py (original) +++ tracker/roundup-src/roundup/__init__.py Fri Nov 27 12:58:04 2009 @@ -68,6 +68,6 @@ ''' __docformat__ = 'restructuredtext' -__version__ = '1.4.8' +__version__ = '1.4.10' # vim: set filetype=python ts=4 sw=4 et si Modified: tracker/roundup-src/roundup/actions.py ============================================================================== --- tracker/roundup-src/roundup/actions.py (original) +++ tracker/roundup-src/roundup/actions.py Fri Nov 27 12:58:04 2009 @@ -64,5 +64,5 @@ if not self.db.security.hasPermission('Edit', self.db.getuid(), classname=classname, itemid=itemid): raise Unauthorised(self._('You do not have permission to ' - '%(action)s the %(classname)s class.')%info) + 'retire the %(classname)s class.')%classname) Modified: tracker/roundup-src/roundup/admin.py ============================================================================== --- tracker/roundup-src/roundup/admin.py (original) +++ tracker/roundup-src/roundup/admin.py Fri Nov 27 12:58:04 2009 @@ -1099,6 +1099,9 @@ if not os.path.exists(dir): os.makedirs(dir) + # maximum csv field length exceeding configured size? + max_len = self.db.config.CSV_FIELD_SIZE + # do all the classes specified for classname in classes: cl = self.get_class(classname) @@ -1121,7 +1124,18 @@ if self.verbose: sys.stdout.write('\rExporting %s - %s'%(classname, nodeid)) sys.stdout.flush() - writer.writerow(cl.export_list(propnames, nodeid)) + node = cl.getnode(nodeid) + exp = cl.export_list(propnames, nodeid) + lensum = sum ([len (repr(node[p])) for p in propnames]) + # for a safe upper bound of field length we add + # difference between CSV len and sum of all field lengths + d = sum ([len(x) for x in exp]) - lensum + assert (d > 0) + for p in propnames: + ll = len(repr(node[p])) + d + if ll > max_len: + max_len = ll + writer.writerow(exp) if export_files and hasattr(cl, 'export_files'): cl.export_files(dir, nodeid) @@ -1136,6 +1150,9 @@ journals = csv.writer(jf, colon_separated) map(journals.writerow, cl.export_journals()) jf.close() + if max_len > self.db.config.CSV_FIELD_SIZE: + print >> sys.stderr, \ + "Warning: config csv_field_size should be at least %s"%max_len return 0 def do_exporttables(self, args): @@ -1177,6 +1194,9 @@ raise UsageError, _('Not enough arguments supplied') from roundup import hyperdb + if hasattr (csv, 'field_size_limit'): + csv.field_size_limit(self.db.config.CSV_FIELD_SIZE) + # directory to import from dir = args[0] @@ -1212,7 +1232,7 @@ if hasattr(cl, 'import_files'): cl.import_files(dir, nodeid) maxid = max(maxid, int(nodeid)) - print + print >> sys.stdout f.close() # import the journals @@ -1222,7 +1242,7 @@ f.close() # set the id counter - print 'setting', classname, maxid+1 + print >> sys.stdout, 'setting', classname, maxid+1 self.db.setid(classname, str(maxid+1)) self.db_uncommitted = True Modified: tracker/roundup-src/roundup/backends/__init__.py ============================================================================== --- tracker/roundup-src/roundup/backends/__init__.py (original) +++ tracker/roundup-src/roundup/backends/__init__.py Fri Nov 27 12:58:04 2009 @@ -31,7 +31,7 @@ 'mysql': ('MySQLdb',), 'postgresql': ('psycopg',), 'tsearch2': ('psycopg',), - 'sqlite': ('pysqlite', 'pysqlite2', 'sqlite3', '_sqlite3'), + 'sqlite': ('pysqlite', 'pysqlite2', 'sqlite3', '_sqlite3', 'sqlite'), } def get_backend(name): Modified: tracker/roundup-src/roundup/backends/back_postgresql.py ============================================================================== --- tracker/roundup-src/roundup/backends/back_postgresql.py (original) +++ tracker/roundup-src/roundup/backends/back_postgresql.py Fri Nov 27 12:58:04 2009 @@ -9,7 +9,7 @@ '''Postgresql backend via psycopg for Roundup.''' __docformat__ = 'restructuredtext' -import os, shutil, popen2, time +import os, shutil, time try: import psycopg from psycopg import QuotedString Modified: tracker/roundup-src/roundup/backends/back_sqlite.py ============================================================================== --- tracker/roundup-src/roundup/backends/back_sqlite.py (original) +++ tracker/roundup-src/roundup/backends/back_sqlite.py Fri Nov 27 12:58:04 2009 @@ -14,8 +14,8 @@ from roundup.backends import rdbms_common sqlite_version = None try: - import sqlite - sqlite_version = 1 + import sqlite3 as sqlite + sqlite_version = 3 except ImportError: try: from pysqlite2 import dbapi2 as sqlite @@ -24,8 +24,8 @@ '- %s found'%sqlite.version) sqlite_version = 2 except ImportError: - import sqlite3 as sqlite - sqlite_version = 3 + import sqlite + sqlite_version = 1 def db_exists(config): return os.path.exists(os.path.join(config.DATABASE, 'db')) @@ -109,10 +109,10 @@ conn = sqlite.connect(db, timeout=30) conn.row_factory = sqlite.Row - # sqlite3 wants us to store Unicode in the db but that's not what's - # been done historically and it's definitely not what the other - # backends do, so we'll stick with UTF-8 - if sqlite_version == 3: + # pysqlite2 / sqlite3 want us to store Unicode in the db but + # that's not what's been done historically and it's definitely + # not what the other backends do, so we'll stick with UTF-8 + if sqlite_version in (2, 3): conn.text_factory = str cursor = conn.cursor() Modified: tracker/roundup-src/roundup/backends/indexer_common.py ============================================================================== --- tracker/roundup-src/roundup/backends/indexer_common.py (original) +++ tracker/roundup-src/roundup/backends/indexer_common.py Fri Nov 27 12:58:04 2009 @@ -22,6 +22,10 @@ self.stopwords = set(STOPWORDS) for word in db.config[('main', 'indexer_stopwords')]: self.stopwords.add(word) + # Do not index anything longer than 25 characters since that'll be + # gibberish (encoded text or somesuch) or shorter than 2 characters + self.minlength = 2 + self.maxlength = 25 def is_stopword(self, word): return word in self.stopwords Modified: tracker/roundup-src/roundup/backends/indexer_dbm.py ============================================================================== --- tracker/roundup-src/roundup/backends/indexer_dbm.py (original) +++ tracker/roundup-src/roundup/backends/indexer_dbm.py Fri Nov 27 12:58:04 2009 @@ -135,14 +135,12 @@ # case insensitive text = str(text).upper() - # Split the raw text, losing anything longer than 25 characters - # since that'll be gibberish (encoded text or somesuch) or shorter - # than 3 characters since those short words appear all over the - # place - return re.findall(r'\b\w{2,25}\b', text) + # Split the raw text + return re.findall(r'\b\w{%d,%d}\b' % (self.minlength, self.maxlength), + text) - # we override this to ignore not 2 < word < 25 and also to fix a bug - - # the (fail) case. + # we override this to ignore too short and too long words + # and also to fix a bug - the (fail) case. def find(self, wordlist): '''Locate files that match ALL the words in wordlist ''' @@ -152,10 +150,12 @@ entries = {} hits = None for word in wordlist: - if not 2 < len(word) < 25: + if not self.minlength <= len(word) <= self.maxlength: # word outside the bounds of what we index - ignore continue word = word.upper() + if self.is_stopword(word): + continue entry = self.words.get(word) # For each word, get index entries[word] = entry # of matching files if not entry: # Nothing for this one word (fail) Modified: tracker/roundup-src/roundup/backends/indexer_rdbms.py ============================================================================== --- tracker/roundup-src/roundup/backends/indexer_rdbms.py (original) +++ tracker/roundup-src/roundup/backends/indexer_rdbms.py Fri Nov 27 12:58:04 2009 @@ -66,11 +66,11 @@ # ok, find all the unique words in the text text = unicode(text, "utf-8", "replace").upper() wordlist = [w.encode("utf-8") - for w in re.findall(r'(?u)\b\w{2,25}\b', text)] + for w in re.findall(r'(?u)\b\w{%d,%d}\b' + % (self.minlength, self.maxlength), text)] words = set() for word in wordlist: if self.is_stopword(word): continue - if len(word) > 25: continue words.add(word) # for each word, add an entry in the db @@ -86,7 +86,9 @@ if not wordlist: return [] - l = [word.upper() for word in wordlist if 26 > len(word) > 2] + l = [word.upper() for word in wordlist + if self.minlength <= len(word) <= self.maxlength] + l = [word for word in l if not self.is_stopword(word)] if not l: return [] Modified: tracker/roundup-src/roundup/backends/indexer_xapian.py ============================================================================== --- tracker/roundup-src/roundup/backends/indexer_xapian.py (original) +++ tracker/roundup-src/roundup/backends/indexer_xapian.py Fri Nov 27 12:58:04 2009 @@ -88,7 +88,9 @@ doc.set_data(identifier) doc.add_posting(identifier, 0) - for match in re.finditer(r'\b\w{2,25}\b', text.upper()): + for match in re.finditer(r'\b\w{%d,%d}\b' + % (self.minlength, self.maxlength), + text.upper()): word = match.group(0) if self.is_stopword(word): continue @@ -112,8 +114,10 @@ enquire = xapian.Enquire(database) stemmer = xapian.Stem("english") terms = [] - for term in [word.upper() for word in wordlist if 26 > len(word) > 2]: - terms.append(stemmer(term.upper())) + for term in [word.upper() for word in wordlist + if self.minlength <= len(word) <= self.maxlength]: + if not self.is_stopword(term): + terms.append(stemmer(term)) query = xapian.Query(xapian.Query.OP_AND, terms) enquire.set_query(query) Modified: tracker/roundup-src/roundup/cgi/PageTemplates/Expressions.py ============================================================================== --- tracker/roundup-src/roundup/cgi/PageTemplates/Expressions.py (original) +++ tracker/roundup-src/roundup/cgi/PageTemplates/Expressions.py Fri Nov 27 12:58:04 2009 @@ -53,7 +53,8 @@ try: from zExceptions import Unauthorized except ImportError: - Unauthorized = "Unauthorized" + class Unauthorized(Exception): + pass def acquisition_security_filter(orig, inst, name, v, real_validate): if real_validate(orig, inst, name, v): Modified: tracker/roundup-src/roundup/cgi/actions.py ============================================================================== --- tracker/roundup-src/roundup/cgi/actions.py (original) +++ tracker/roundup-src/roundup/cgi/actions.py Fri Nov 27 12:58:04 2009 @@ -544,9 +544,25 @@ Base behaviour is to check the user can edit this class. No additional property checks are made. """ + if not classname : classname = self.client.classname - return self.hasPermission('Create', classname=classname) + + if not self.hasPermission('Create', classname=classname): + return 0 + + # Check Edit permission for each property, to avoid being able + # to set restricted ones on new item creation + for key in props: + if not self.hasPermission('Edit', classname=classname, + property=key): + # We restrict by default and special-case allowed properties + if key == 'date' or key == 'content': + continue + elif key == 'author' and props[key] == self.userid: + continue + return 0 + return 1 class EditItemAction(EditCommon): def lastUserActivity(self): @@ -648,11 +664,6 @@ % str(message)) return - # guard against new user creation that would bypass security checks - for key in props: - if 'user' in key: - return - # handle the props - edit or create try: # when it hits the None element, it'll set self.nodeid @@ -814,7 +825,7 @@ class RegisterAction(RegoCommon, EditCommon): name = 'register' - permissionType = 'Create' + permissionType = 'Register' def handle(self): """Attempt to create a new user based on the contents of the form Modified: tracker/roundup-src/roundup/cgi/apache.py ============================================================================== --- tracker/roundup-src/roundup/cgi/apache.py (original) +++ tracker/roundup-src/roundup/cgi/apache.py Fri Nov 27 12:58:04 2009 @@ -10,21 +10,10 @@ # This module operates with only one tracker # and must be placed in the tracker directory. # -# History (most recent first): -# 11-jul-2004 [als] added 'TrackerLanguage' option; -# pass message translator to the tracker client instance -# 04-jul-2004 [als] tracker lookup moved from module global to request handler; -# use PythonOption TrackerHome (configured in apache) -# to open the tracker -# 06-may-2004 [als] use cgi.FieldStorage from Python library -# instead of mod_python FieldStorage -# 29-apr-2004 [als] created - -__version__ = "$Revision: 1.6 $"[11:-2] -__date__ = "$Date: 2006-11-09 00:36:21 $"[7:-2] import cgi import os +import threading from mod_python import apache @@ -83,6 +72,15 @@ return self._req.sendfile(filename, offset, len) +__tracker_cache = {} +"""A cache of optimized tracker instances. + +The keys are strings giving the directories containing the trackers. +The values are tracker instances.""" + +__tracker_cache_lock = threading.Lock() +"""A lock used to guard access to the cache.""" + def handler(req): """HTTP request handler""" @@ -94,12 +92,31 @@ _timing = "" _debug = _options.get("TrackerDebug", "no") _debug = _debug.lower() not in ("no", "false") - if not (_home and os.path.isdir(_home)): - apache.log_error( - "PythonOption TrackerHome missing or invalid for %(uri)s" - % {'uri': req.uri}) - return apache.HTTP_INTERNAL_SERVER_ERROR - _tracker = roundup.instance.open(_home, not _debug) + + # We do not need to take a lock here (the fast path) because reads + # from dictionaries are atomic. + if not _debug and _home in __tracker_cache: + _tracker = __tracker_cache[_home] + else: + if not (_home and os.path.isdir(_home)): + apache.log_error( + "PythonOption TrackerHome missing or invalid for %(uri)s" + % {'uri': req.uri}) + return apache.HTTP_INTERNAL_SERVER_ERROR + if _debug: + _tracker = roundup.instance.open(_home, optimize=0) + else: + __tracker_cache_lock.acquire() + try: + # The tracker may have been added while we were acquiring + # the lock. + if _home in __tracker_cache: + _tracker = __tracker_cache[home] + else: + _tracker = roundup.instance.open(_home, optimize=1) + __tracker_cache[_home] = _tracker + finally: + __tracker_cache_lock.release() # create environment # Note: cookies are read from HTTP variables, so we need all HTTP vars req.add_common_vars() Modified: tracker/roundup-src/roundup/cgi/cgitb.py ============================================================================== --- tracker/roundup-src/roundup/cgi/cgitb.py (original) +++ tracker/roundup-src/roundup/cgi/cgitb.py Fri Nov 27 12:58:04 2009 @@ -37,7 +37,10 @@ def niceDict(indent, dict): l = [] - for k,v in dict.items(): + keys = dict.keys() + keys.sort() + for k in keys: + v = dict[k] l.append('%s%s'%(k, cgi.escape(repr(v)))) return '\n'.join(l) Modified: tracker/roundup-src/roundup/cgi/client.py ============================================================================== --- tracker/roundup-src/roundup/cgi/client.py (original) +++ tracker/roundup-src/roundup/cgi/client.py Fri Nov 27 12:58:04 2009 @@ -387,7 +387,6 @@ self.translator, allow_none=True) output = handler.dispatch(input) - self.db.commit() self.setHeader("Content-Type", "text/xml") self.setHeader("Content-Length", str(len(output))) @@ -490,13 +489,23 @@ self.additional_headers['Location'] = str(url) self.response_code = 302 self.write_html('Redirecting to %s'%(url, url)) + except LoginError, message: + # The user tried to log in, but did not provide a valid + # username and password. If we support HTTP + # authorization, send back a response that will cause the + # browser to prompt the user again. + if self.instance.config.WEB_HTTP_AUTH: + self.response_code = httplib.UNAUTHORIZED + realm = self.instance.config.TRACKER_NAME + self.setHeader("WWW-Authenticate", + "Basic realm=\"%s\"" % realm) + else: + self.response_code = httplib.FORBIDDEN + self.renderFrontPage(message) except Unauthorised, message: # users may always see the front page self.response_code = 403 - self.classname = self.nodeid = None - self.template = '' - self.error_message.append(message) - self.write_html(self.renderContext()) + self.renderFrontPage(message) except NotModified: # send the 304 response self.response_code = 304 @@ -516,11 +525,22 @@ self.error_message.append(self._('Form Error: ') + str(e)) self.write_html(self.renderContext()) except: - if self.instance.config.WEB_DEBUG: - self.write_html(cgitb.html(i18n=self.translator)) + # Something has gone badly wrong. Therefore, we should + # make sure that the response code indicates failure. + if self.response_code == httplib.OK: + self.response_code = httplib.INTERNAL_SERVER_ERROR + # Help the administrator work out what went wrong. + html = ("

    Traceback

    " + + cgitb.html(i18n=self.translator) + + ("

    Environment Variables

    %s
    " + % cgitb.niceDict("", self.env))) + if not self.instance.config.WEB_DEBUG: + exc_info = sys.exc_info() + subject = "Error: %s" % exc_info[1] + self.send_html_to_admin(subject, html) + self.write_html(self._(error_message)) else: - self.mailer.exception_message(self.exception_data()) - return self.write_html(self._(error_message)) + self.write_html(html) def exception_data(self): result = '' @@ -700,7 +720,7 @@ login.verifyLogin(username, password) except LoginError, err: self.make_user_anonymous() - raise Unauthorised, err + raise user = username # if user was not set by http authorization, try session lookup @@ -755,6 +775,10 @@ else: self.db.close() self.db = self.instance.open(username) + # The old session API refers to the closed database; + # we can no longer use it. + self.session_api = Session(self) + def determine_context(self, dre=re.compile(r'([^\d]+)0*(\d+)')): """Determine the context of this page from the URL: @@ -873,7 +897,12 @@ raise NotFound, str(designator) classname, nodeid = m.group(1), m.group(2) - klass = self.db.getclass(classname) + try: + klass = self.db.getclass(classname) + except KeyError: + # The classname was not valid. + raise NotFound, str(designator) + # make sure we have the appropriate properties props = klass.getprops() @@ -980,6 +1009,25 @@ self.additional_headers['Content-Length'] = str(len(content)) self.write(content) + def send_html_to_admin(self, subject, content): + + to = [self.mailer.config.ADMIN_EMAIL] + message = self.mailer.get_standard_message(to, subject) + # delete existing content-type headers + del message['Content-type'] + message['Content-type'] = 'text/html; charset=utf-8' + message.set_payload(content) + encode_quopri(message) + self.mailer.smtp_send(to, str(message)) + + def renderFrontPage(self, message): + """Return the front page of the tracker.""" + + self.classname = self.nodeid = None + self.template = '' + self.error_message.append(message) + self.write_html(self.renderContext()) + def renderContext(self): """ Return a PageTemplate for the named page """ @@ -1026,16 +1074,8 @@ try: # If possible, send the HTML page template traceback # to the administrator. - to = [self.mailer.config.ADMIN_EMAIL] subject = "Templating Error: %s" % exc_info[1] - content = cgitb.pt_html() - message = self.mailer.get_standard_message(to, subject) - # delete existing content-type headers - del message['Content-type'] - message['Content-type'] = 'text/html; charset=utf-8' - message.set_payload(content) - encode_quopri(message) - self.mailer.smtp_send(to, str(message)) + self.send_html_to_admin(subject, cgitb.pt_html()) # Now report the error to the user. return self._(self.error_message) except: @@ -1361,7 +1401,7 @@ # RFC 2616 14.13: Content-Length # # Tell the client how much data we are providing. - self.setHeader("Content-Length", length) + self.setHeader("Content-Length", str(length)) # Send the HTTP header. self.header() # If the client doesn't actually want the body, or if we are Modified: tracker/roundup-src/roundup/cgi/form_parser.py ============================================================================== --- tracker/roundup-src/roundup/cgi/form_parser.py (original) +++ tracker/roundup-src/roundup/cgi/form_parser.py Fri Nov 27 12:58:04 2009 @@ -427,7 +427,7 @@ value = existing # Sort the value in the same order used by # Multilink.from_raw. - value.sort(key = lambda x: int(x)) + value.sort(lambda x, y: cmp(int(x),int(y))) elif value == '': # other types should be None'd if there's no value @@ -491,7 +491,7 @@ # The canonical order (given in Multilink.from_raw) is # by the numeric value of the IDs. if isinstance(proptype, hyperdb.Multilink): - existing.sort(key = lambda x: int(x)) + existing.sort(lambda x, y: cmp(int(x),int(y))) # "missing" existing values may not be None if not existing: Modified: tracker/roundup-src/roundup/cgi/templating.py ============================================================================== --- tracker/roundup-src/roundup/cgi/templating.py (original) +++ tracker/roundup-src/roundup/cgi/templating.py Fri Nov 27 12:58:04 2009 @@ -183,12 +183,28 @@ return self.templates[src] # compile the template - self.templates[src] = pt = RoundupPageTemplate() + pt = RoundupPageTemplate() # use pt_edit so we can pass the content_type guess too content_type = mimetypes.guess_type(filename)[0] or 'text/html' pt.pt_edit(open(src).read(), content_type) pt.id = filename pt.mtime = stime + # Add it to the cache. We cannot do this until the template + # is fully initialized, as we could otherwise have a race + # condition when running with multiple threads: + # + # 1. Thread A notices the template is not in the cache, + # adds it, but has not yet set "mtime". + # + # 2. Thread B notices the template is in the cache, checks + # "mtime" (above) and crashes. + # + # Since Python dictionary access is atomic, as long as we + # insert "pt" only after it is fully initialized, we avoid + # this race condition. It's possible that two separate + # threads will both do the work of initializing the template, + # but the risk of wasted work is offset by avoiding a lock. + self.templates[src] = pt return pt def __getitem__(self, name): @@ -420,17 +436,19 @@ except KeyError: pass +def cgi_escape_attrs(**attrs): + return ' '.join(['%s="%s"'%(k,cgi.escape(str(v), True)) + for k,v in attrs.items()]) + def input_html4(**attrs): """Generate an 'input' (html4) element with given attributes""" _set_input_default_args(attrs) - return ''%' '.join(['%s="%s"'%(k,cgi.escape(str(v), True)) - for k,v in attrs.items()]) + return ''%cgi_escape_attrs(**attrs) def input_xhtml(**attrs): """Generate an 'input' (xhtml) element with given attributes""" _set_input_default_args(attrs) - return ''%' '.join(['%s="%s"'%(k,cgi.escape(str(v), True)) - for k,v in attrs.items()]) + return ''%cgi_escape_attrs(**attrs) class HTMLInputMixin: """ requires a _client property """ @@ -880,7 +898,8 @@ # XXX do this return [] - def history(self, direction='descending', dre=re.compile('^\d+$')): + def history(self, direction='descending', dre=re.compile('^\d+$'), + limit=None): if not self.is_view_ok(): return self._('[hidden]') @@ -912,6 +931,10 @@ history.sort() history.reverse() + # restrict the volume + if limit: + history = history[:limit] + timezone = self._db.getUserTimezone() l = [] comments = {} @@ -1268,7 +1291,9 @@ return self._db.security.hasPermission('Edit', self._client.userid, self._classname, self._name, self._nodeid) return self._db.security.hasPermission('Create', self._client.userid, - self._classname, self._name) + self._classname, self._name) or \ + self._db.security.hasPermission('Register', self._client.userid, + self._classname, self._name) def is_view_ok(self): """ Is the user allowed to View the current class? @@ -1457,8 +1482,7 @@ value = '"'.join(value.split('"')) name = self._formname - passthrough_args = ' '.join(['%s="%s"' % (k, cgi.escape(str(v), True)) - for k,v in kwargs.items()]) + passthrough_args = cgi_escape_attrs(**kwargs) return ('') % locals() @@ -1496,7 +1520,7 @@ return '' return self._('*encrypted*') - def field(self, size=30): + def field(self, size=30, **kwargs): """ Render a form edit field for the property. If not editable, just display the value via plain(). @@ -1504,7 +1528,8 @@ if not self.is_edit_ok(): return self.plain(escape=1) - return self.input(type="password", name=self._formname, size=size) + return self.input(type="password", name=self._formname, size=size, + **kwargs) def confirm(self, size=30): """ Render a second form edit field for the property, used for @@ -1533,7 +1558,7 @@ return str(self._value) - def field(self, size=30): + def field(self, size=30, **kwargs): """ Render a form edit field for the property. If not editable, just display the value via plain(). @@ -1545,7 +1570,8 @@ if value is None: value = '' - return self.input(name=self._formname, value=value, size=size) + return self.input(name=self._formname, value=value, size=size, + **kwargs) def __int__(self): """ Return an int of me @@ -1569,7 +1595,7 @@ return '' return self._value and self._("Yes") or self._("No") - def field(self): + def field(self, **kwargs): """ Render a form edit field for the property If not editable, just display the value via plain(). @@ -1585,15 +1611,17 @@ checked = value and "checked" or "" if value: s = self.input(type="radio", name=self._formname, value="yes", - checked="checked") + checked="checked", **kwargs) s += self._('Yes') - s +=self.input(type="radio", name=self._formname, value="no") + s +=self.input(type="radio", name=self._formname, value="no", + **kwargs) s += self._('No') else: - s = self.input(type="radio", name=self._formname, value="yes") + s = self.input(type="radio", name=self._formname, value="yes", + **kwargs) s += self._('Yes') s +=self.input(type="radio", name=self._formname, value="no", - checked="checked") + checked="checked", **kwargs) s += self._('No') return s @@ -1651,7 +1679,8 @@ return DateHTMLProperty(self._client, self._classname, self._nodeid, self._prop, self._formname, ret) - def field(self, size=30, default=None, format=_marker, popcal=True): + def field(self, size=30, default=None, format=_marker, popcal=True, + **kwargs): """Render a form edit field for the property If not editable, just display the value via plain(). @@ -1686,7 +1715,8 @@ elif isinstance(value, str) or isinstance(value, unicode): # most likely erroneous input to be passed back to user if isinstance(value, unicode): value = value.encode('utf8') - return self.input(name=self._formname, value=value, size=size) + return self.input(name=self._formname, value=value, size=size, + **kwargs) else: raw_value = value @@ -1706,7 +1736,8 @@ if format is not self._marker: value = value.pretty(format) - s = self.input(name=self._formname, value=value, size=size) + s = self.input(name=self._formname, value=value, size=size, + **kwargs) if popcal: s += self.popcal() return s @@ -1801,7 +1832,7 @@ return self._value.pretty() - def field(self, size=30): + def field(self, size=30, **kwargs): """ Render a form edit field for the property If not editable, just display the value via plain(). @@ -1813,7 +1844,8 @@ if value is None: value = '' - return self.input(name=self._formname, value=value, size=size) + return self.input(name=self._formname, value=value, size=size, + **kwargs) class LinkHTMLProperty(HTMLProperty): """ Link HTMLProperty @@ -1866,7 +1898,7 @@ value = cgi.escape(value) return value - def field(self, showid=0, size=None): + def field(self, showid=0, size=None, **kwargs): """ Render a form edit field for the property If not editable, just display the value via plain(). @@ -1884,10 +1916,11 @@ value = linkcl.get(self._value, k) else: value = self._value - return self.input(name=self._formname, value=value, size=size) + return self.input(name=self._formname, value=value, size=size, + **kwargs) def menu(self, size=None, height=None, showid=0, additional=[], value=None, - sort_on=None, **conditions): + sort_on=None, html_kwargs = {}, **conditions): """ Render a form select list for this property "size" is used to limit the length of the list labels @@ -1920,7 +1953,8 @@ value = None linkcl = self._db.getclass(self._prop.classname) - l = [''%cgi_escape_attrs(name = self._formname, + **html_kwargs)] k = linkcl.labelprop(1) s = '' if value is None: @@ -2086,7 +2120,7 @@ value = cgi.escape(value) return value - def field(self, size=30, showid=0): + def field(self, size=30, showid=0, **kwargs): """ Render a form edit field for the property If not editable, just display the value via plain(). @@ -2103,10 +2137,11 @@ k = linkcl.labelprop(1) value = lookupKeys(linkcl, k, value) value = ','.join(value) - return self.input(name=self._formname, size=size, value=value) + return self.input(name=self._formname, size=size, value=value, + **kwargs) def menu(self, size=None, height=None, showid=0, additional=[], - value=None, sort_on=None, **conditions): + value=None, sort_on=None, html_kwargs = {}, **conditions): """ Render a form '%(self._formname, height)] + l = [' - + +
    +

    body title

    +
    @@ -136,7 +136,7 @@ Register
    Lost your login?

    @@ -164,7 +164,7 @@

    Help
    - Roundup docs

    Modified: tracker/roundup-src/share/roundup/templates/classic/html/style.css ============================================================================== --- tracker/roundup-src/share/roundup/templates/classic/html/style.css (original) +++ tracker/roundup-src/share/roundup/templates/classic/html/style.css Fri Nov 27 12:58:04 2009 @@ -50,14 +50,6 @@ padding: 5px; border-bottom: 1px solid #444; } -#searchbox { - float: right; -} - -div#body-title { - float: left; -} - div#searchbox { float: right; Modified: tracker/roundup-src/share/roundup/templates/classic/schema.py ============================================================================== --- tracker/roundup-src/share/roundup/templates/classic/schema.py (original) +++ tracker/roundup-src/share/roundup/templates/classic/schema.py Fri Nov 27 12:58:04 2009 @@ -47,6 +47,8 @@ roles=String(), # comma-separated string of Role names timezone=String()) user.setkey("username") +db.security.addPermission(name='Register', klass='user', + description='User is allowed to register new user') # FileClass automatically gets this property in addition to the Class ones: # content = String() [saved to disk in /db/files/] @@ -154,7 +156,7 @@ # Assign the appropriate permissions to the anonymous user's Anonymous # Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # Allow anonymous users access to view issues (and the related, linked # information) Modified: tracker/roundup-src/share/roundup/templates/minimal/html/_generic.item.html ============================================================================== --- tracker/roundup-src/share/roundup/templates/minimal/html/_generic.item.html (original) +++ tracker/roundup-src/share/roundup/templates/minimal/html/_generic.item.html Fri Nov 27 12:58:04 2009 @@ -9,18 +9,18 @@ -You are not allowed to view this page. - -Please login with your username and password. +

    + You are not allowed to view this page.

    + +

    + Please login with your username and password.

    + +
    @@ -44,21 +44,14 @@
    - - - - - - - - -
    - + +

    Showing 10 items. +Show all history +(warning: this could be VERY long)

    - - - +
    Modified: tracker/roundup-src/share/roundup/templates/minimal/html/page.html ============================================================================== --- tracker/roundup-src/share/roundup/templates/minimal/html/page.html (original) +++ tracker/roundup-src/share/roundup/templates/minimal/html/page.html Fri Nov 27 12:58:04 2009 @@ -135,7 +135,7 @@ Register
    Lost your login?

    @@ -151,7 +151,7 @@

    Help
    - Roundup docs

    Modified: tracker/roundup-src/share/roundup/templates/minimal/html/user.item.html ============================================================================== --- tracker/roundup-src/share/roundup/templates/minimal/html/user.item.html (original) +++ tracker/roundup-src/share/roundup/templates/minimal/html/user.item.html Fri Nov 27 12:58:04 2009 @@ -1,4 +1,3 @@ - @@ -57,10 +56,6 @@ confirm_input templates/page/macros/user_confirm_input; edit_ok context/is_edit_ok; "> - - Name - - Login Name @@ -91,51 +86,6 @@ - - Phone - - - - - Organisation - - - - - Timezone - - (this is a numeric hour offset, the default is - ) - - - - - E-mail address - - calvin at the-z.org - - - -   - - - - - - - - - -   Modified: tracker/roundup-src/share/roundup/templates/minimal/schema.py ============================================================================== --- tracker/roundup-src/share/roundup/templates/minimal/schema.py (original) +++ tracker/roundup-src/share/roundup/templates/minimal/schema.py Fri Nov 27 12:58:04 2009 @@ -60,6 +60,6 @@ # Assign the appropriate permissions to the anonymous user's # Anonymous Role. Choices here are: # - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') +db.security.addPermissionToRole('Anonymous', 'Register', 'user') # vim: set et sts=4 sw=4 : Modified: tracker/roundup-src/test/db_test_base.py ============================================================================== --- tracker/roundup-src/test/db_test_base.py (original) +++ tracker/roundup-src/test/db_test_base.py Fri Nov 27 12:58:04 2009 @@ -1613,6 +1613,18 @@ # XXX add sorting tests for other types + # nuke and re-create db for restore + def nukeAndCreate(self): + # shut down this db and nuke it + self.db.close() + self.nuke_database() + + # open a new, empty database + os.makedirs(config.DATABASE + '/files') + self.db = self.module.Database(config, 'admin') + setupSchema(self.db, 0, self.module) + + def testImportExport(self): # use the filtering setup to create a bunch of items ae, filt = self.filteringSetup() @@ -1660,14 +1672,7 @@ klass.export_files('_test_export', id) journals[cn] = klass.export_journals() - # shut down this db and nuke it - self.db.close() - self.nuke_database() - - # open a new, empty database - os.makedirs(config.DATABASE + '/files') - self.db = self.module.Database(config, 'admin') - setupSchema(self.db, 0, self.module) + self.nukeAndCreate() # import for cn, items in export.items(): @@ -1730,6 +1735,58 @@ newid = self.db.user.create(username='testing') assert newid > maxid + # test import/export via admin interface + def testAdminImportExport(self): + import roundup.admin + import csv + # use the filtering setup to create a bunch of items + ae, filt = self.filteringSetup() + # create large field + self.db.priority.create(name = 'X' * 500) + self.db.config.CSV_FIELD_SIZE = 400 + self.db.commit() + output = [] + # ugly hack to get stderr output and disable stdout output + # during regression test. Depends on roundup.admin not using + # anything but stdout/stderr from sys (which is currently the + # case) + def stderrwrite(s): + output.append(s) + roundup.admin.sys = MockNull () + try: + roundup.admin.sys.stderr.write = stderrwrite + tool = roundup.admin.AdminTool() + home = '.' + tool.tracker_home = home + tool.db = self.db + tool.verbose = False + tool.do_export (['_test_export']) + self.assertEqual(len(output), 2) + self.assertEqual(output [1], '\n') + self.failUnless(output [0].startswith + ('Warning: config csv_field_size should be at least')) + self.failUnless(int(output[0].split()[-1]) > 500) + + if hasattr(roundup.admin.csv, 'field_size_limit'): + self.nukeAndCreate() + self.db.config.CSV_FIELD_SIZE = 400 + tool = roundup.admin.AdminTool() + tool.tracker_home = home + tool.db = self.db + tool.verbose = False + self.assertRaises(csv.Error, tool.do_import, ['_test_export']) + + self.nukeAndCreate() + self.db.config.CSV_FIELD_SIZE = 3200 + tool = roundup.admin.AdminTool() + tool.tracker_home = home + tool.db = self.db + tool.verbose = False + tool.do_import(['_test_export']) + finally: + roundup.admin.sys = sys + shutil.rmtree('_test_export') + def testAddProperty(self): self.db.issue.create(title="spam", status='1') self.db.commit() Modified: tracker/roundup-src/test/test_anypy_hashlib.py ============================================================================== --- tracker/roundup-src/test/test_anypy_hashlib.py (original) +++ tracker/roundup-src/test/test_anypy_hashlib.py Fri Nov 27 12:58:04 2009 @@ -39,7 +39,7 @@ class TestCase_anypy_hashlib(unittest.TestCase): """test the hashlib compatibility layer""" - testdata = ( + data_for_test = ( ('', 'da39a3ee5e6b4b0d3255bfef95601890afd80709', 'd41d8cd98f00b204e9800998ecf8427e'), @@ -58,12 +58,12 @@ # the following two are always excecuted: def test_sha1_expected_anypy(self): """...anypy.hashlib_.sha1().hexdigest() yields expected results""" - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(roundup.anypy.hashlib_.sha1(src).hexdigest(), SHA) def test_md5_expected_anypy(self): """...anypy.hashlib_.md5().hexdigest() yields expected results""" - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(roundup.anypy.hashlib_.md5(src).hexdigest(), MD5) # execution depending on availability of modules: @@ -73,14 +73,14 @@ if md5.md5 is hashlib.md5: return else: - for s, i1, i2 in self.testdata: + for s, i1, i2 in self.data_for_test: self.assertEqual(md5.md5(s).digest(), hashlib.md5().digest()) if md5: def test_md5_expected(self): """md5.md5().hexdigest() yields expected results""" - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(md5.md5(src).hexdigest(), MD5) def test_md5_new_expected(self): @@ -88,7 +88,7 @@ if md5.new is md5.md5: return else: - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(md5.new(src).hexdigest(), MD5) if sha and hashlib: @@ -97,14 +97,14 @@ if sha.sha is hashlib.sha1: return else: - for s in self.testdata: + for s in self.data_for_test: self.assertEqual(sha.sha(s).digest(), hashlib.sha1().digest()) if sha: def test_sha_expected(self): """sha.sha().hexdigest() yields expected results""" - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(sha.sha(src).hexdigest(), SHA) # fails for me with Python 2.3; unittest module bug? @@ -113,18 +113,18 @@ if sha.new is sha.sha: return else: - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(sha.new(src).hexdigest(), SHA) if hashlib: def test_sha1_expected_hashlib(self): """hashlib.sha1().hexdigest() yields expected results""" - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(hashlib.sha1(src).hexdigest(), SHA) def test_md5_expected_hashlib(self): """hashlib.md5().hexdigest() yields expected results""" - for src, SHA, MD5 in self.testdata: + for src, SHA, MD5 in self.data_for_test: self.assertEqual(hashlib.md5(src).hexdigest(), MD5) def test_suite(): Modified: tracker/roundup-src/test/test_indexer.py ============================================================================== --- tracker/roundup-src/test/test_indexer.py (original) +++ tracker/roundup-src/test/test_indexer.py Fri Nov 27 12:58:04 2009 @@ -82,6 +82,48 @@ self.dex.add_text(('test', '1', 'foo'), '') self.assertSeqEqual(self.dex.find(['world']), [('test', '2', 'foo')]) + def test_stopwords(self): + """Test that we can find a text with a stopword in it.""" + stopword = "with" + self.assert_(self.dex.is_stopword(stopword.upper())) + self.dex.add_text(('test', '1', 'bar'), '%s hello world' % stopword) + self.dex.add_text(('test', '2', 'bar'), 'blah a %s world' % stopword) + self.dex.add_text(('test', '3', 'bar'), 'blah Blub river') + self.dex.add_text(('test', '4', 'bar'), 'blah river %s' % stopword) + self.assertSeqEqual(self.dex.find(['with','world']), + [('test', '1', 'bar'), + ('test', '2', 'bar')]) + def test_extremewords(self): + """Testing too short or too long words.""" + short = "b" + long = "abcdefghijklmnopqrstuvwxyz" + self.dex.add_text(('test', '1', 'a'), '%s hello world' % short) + self.dex.add_text(('test', '2', 'a'), 'blah a %s world' % short) + self.dex.add_text(('test', '3', 'a'), 'blah Blub river') + self.dex.add_text(('test', '4', 'a'), 'blah river %s %s' + % (short, long)) + self.assertSeqEqual(self.dex.find([short,'world', long, short]), + [('test', '1', 'a'), + ('test', '2', 'a')]) + self.assertSeqEqual(self.dex.find([long]),[]) + + # special test because some faulty code indexed length(word)>=2 + # but only considered length(word)>=3 to be significant + self.dex.add_text(('test', '5', 'a'), 'blah py %s %s' + % (short, long)) + self.assertSeqEqual(self.dex.find(["py"]), [('test', '5', 'a')]) + + def test_casesensitity(self): + """Test if searches are case-in-sensitive.""" + self.dex.add_text(('test', '1', 'a'), 'aaaa bbbb') + self.dex.add_text(('test', '2', 'a'), 'aAaa BBBB') + self.assertSeqEqual(self.dex.find(['aaaa']), + [('test', '1', 'a'), + ('test', '2', 'a')]) + self.assertSeqEqual(self.dex.find(['BBBB']), + [('test', '1', 'a'), + ('test', '2', 'a')]) + def tearDown(self): shutil.rmtree('test-index') Modified: tracker/roundup-src/test/test_mailgw.py ============================================================================== --- tracker/roundup-src/test/test_mailgw.py (original) +++ tracker/roundup-src/test/test_mailgw.py Fri Nov 27 12:58:04 2009 @@ -51,6 +51,7 @@ if not new == old: res = [] + replace = {} for key in new.keys(): if key.startswith('from '): # skip the unix from line @@ -60,11 +61,18 @@ if new[key] != __version__: res.append(' %s: %r != %r' % (key, __version__, new[key])) + elif key.lower() == 'content-type' and 'boundary=' in new[key]: + # handle mime messages + newmime = new[key].split('=',1)[-1].strip('"') + oldmime = old.get(key, '').split('=',1)[-1].strip('"') + replace ['--' + newmime] = '--' + oldmime + replace ['--' + newmime + '--'] = '--' + oldmime + '--' elif new.get(key, '') != old.get(key, ''): res.append(' %s: %r != %r' % (key, old.get(key, ''), new.get(key, ''))) - body_diff = self.compareStrings(new.fp.read(), old.fp.read()) + body_diff = self.compareStrings(new.fp.read(), old.fp.read(), + replace=replace) if body_diff: res.append('') res.extend(body_diff) @@ -73,13 +81,14 @@ res.insert(0, 'Generated message not correct (diff follows):') raise AssertionError, '\n'.join(res) - def compareStrings(self, s2, s1): + def compareStrings(self, s2, s1, replace={}): '''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants the first to be the "original" but in the calls in this file, the second arg is the original. Ho hum. + Do replacements over the replace dict -- used for mime boundary ''' l1 = s1.strip().split('\n') - l2 = s2.strip().split('\n') + l2 = [replace.get(i,i) for i in s2.strip().split('\n')] if l1 == l2: return s = difflib.SequenceMatcher(None, l1, l2) @@ -116,11 +125,11 @@ address='chef at bork.bork.bork', realname='Bork, Chef', roles='User') self.richard_id = self.db.user.create(username='richard', address='richard at test.test', roles='User') - self.mary_id = self.db.user.create(username='mary', address='mary at test.test', - roles='User', realname='Contrary, Mary') - self.john_id = self.db.user.create(username='john', address='john at test.test', - alternate_addresses='jondoe at test.test\njohn.doe at test.test', roles='User', - realname='John Doe') + self.mary_id = self.db.user.create(username='mary', + address='mary at test.test', roles='User', realname='Contrary, Mary') + self.john_id = self.db.user.create(username='john', + address='john at test.test', roles='User', realname='John Doe', + alternate_addresses='jondoe at test.test\njohn.doe at test.test') def tearDown(self): if os.path.exists(SENDMAILDEBUG): @@ -132,11 +141,15 @@ if error.errno not in (errno.ENOENT, errno.ESRCH): raise def _handle_mail(self, message): - handler = self.instance.MailGW(self.instance, self.db) + # handler will open a new db handle. On single-threaded + # databases we'll have to close our current connection + self.db.commit() + self.db.close() + handler = self.instance.MailGW(self.instance) handler.trapExceptions = 0 ret = handler.main(StringIO(message)) - # handler can close the db on us and open a new one - self.db = handler.db + # handler had its own database, open new connection + self.db = self.instance.open('admin') return ret def _get_mail(self): @@ -549,6 +562,11 @@ self.doNewIssue() oldvalues = self.db.getnode('issue', '1').copy() oldvalues['assignedto'] = None + # reconstruct old behaviour: This would reuse the + # database-handle from the doNewIssue above which has committed + # as user "Chef". So we close and reopen the db as that user. + self.db.close() + self.db = self.instance.open('Chef') self.db.issue.set('1', assignedto=self.chef_id) self.db.commit() self.db.issue.nosymessage('1', None, oldvalues) @@ -990,11 +1008,6 @@ assert not os.path.exists(SENDMAILDEBUG) def testNewUserAuthor(self): - # first without the permission - # heh... just ignore the API for a second ;) - self.db.security.role['anonymous'].permissions=[] - anonid = self.db.user.lookup('anonymous') - self.db.user.set(anonid, roles='Anonymous') l = self.db.user.list() l.sort() @@ -1007,6 +1020,12 @@ This is a test submission of a new issue. ''' + def hook (db, **kw): + ''' set up callback for db open ''' + db.security.role['anonymous'].permissions=[] + anonid = db.user.lookup('anonymous') + db.user.set(anonid, roles='Anonymous') + self.instance.schema_hook = hook try: self._handle_mail(message) except Unauthorized, value: @@ -1021,15 +1040,17 @@ else: raise AssertionError, "Unathorized not raised when handling mail" - # Add Web Access role to anonymous, and try again to make sure - # we get a "please register at:" message this time. - p = [ - self.db.security.getPermission('Create', 'user'), - self.db.security.getPermission('Web Access', None), - ] - - self.db.security.role['anonymous'].permissions=p + def hook (db, **kw): + ''' set up callback for db open ''' + # Add Web Access role to anonymous, and try again to make sure + # we get a "please register at:" message this time. + p = [ + db.security.getPermission('Create', 'user'), + db.security.getPermission('Web Access', None), + ] + db.security.role['anonymous'].permissions=p + self.instance.schema_hook = hook try: self._handle_mail(message) except Unauthorized, value: @@ -1053,12 +1074,15 @@ m.sort() self.assertEqual(l, m) - # now with the permission - p = [ - self.db.security.getPermission('Create', 'user'), - self.db.security.getPermission('Email Access', None), - ] - self.db.security.role['anonymous'].permissions=p + def hook (db, **kw): + ''' set up callback for db open ''' + # now with the permission + p = [ + db.security.getPermission('Create', 'user'), + db.security.getPermission('Email Access', None), + ] + db.security.role['anonymous'].permissions=p + self.instance.schema_hook = hook self._handle_mail(message) m = self.db.user.list() m.sort() @@ -1076,17 +1100,80 @@ This is a test submission of a new issue. ''' - p = [ - self.db.security.getPermission('Create', 'user'), - self.db.security.getPermission('Email Access', None), - ] - self.db.security.role['anonymous'].permissions=p + def hook (db, **kw): + ''' set up callback for db open ''' + p = [ + db.security.getPermission('Create', 'user'), + db.security.getPermission('Email Access', None), + ] + db.security.role['anonymous'].permissions=p + self.instance.schema_hook = hook self._handle_mail(message) m = set(self.db.user.list()) new = list(m - l)[0] name = self.db.user.get(new, 'realname') self.assertEquals(name, 'H???llo') + def testUnknownUser(self): + l = set(self.db.user.list()) + message = '''Content-Type: text/plain; + charset="iso-8859-1" +From: Nonexisting User +To: issue_tracker at your.tracker.email.domain.example +Message-Id: +Subject: [issue] Testing nonexisting user... + +This is a test submission of a new issue. +''' + self.db.close() + handler = self.instance.MailGW(self.instance) + # we want a bounce message: + handler.trapExceptions = 1 + ret = handler.main(StringIO(message)) + self.compareMessages(self._get_mail(), +'''FROM: Roundup issue tracker +TO: nonexisting at bork.bork.bork +From nobody Tue Jul 14 12:04:11 2009 +Content-Type: multipart/mixed; boundary="===============0639262320==" +MIME-Version: 1.0 +Subject: Failed issue tracker submission +To: nonexisting at bork.bork.bork +From: Roundup issue tracker +Date: Tue, 14 Jul 2009 12:04:11 +0000 +Precedence: bulk +X-Roundup-Name: Roundup issue tracker +X-Roundup-Loop: hello +X-Roundup-Version: 1.4.8 +MIME-Version: 1.0 + +--===============0639262320== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit + + + +You are not a registered user. + +Unknown address: nonexisting at bork.bork.bork + +--===============0639262320== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit + +Content-Type: text/plain; + charset="iso-8859-1" +From: Nonexisting User +To: issue_tracker at your.tracker.email.domain.example +Message-Id: +Subject: [issue] Testing nonexisting user... + +This is a test submission of a new issue. + +--===============0639262320==-- +''') + def testEnc01(self): self.doNewIssue() self._handle_mail('''Content-Type: text/plain; Modified: tracker/roundup-src/test/test_xmlrpc.py ============================================================================== --- tracker/roundup-src/test/test_xmlrpc.py (original) +++ tracker/roundup-src/test/test_xmlrpc.py Fri Nov 27 12:58:04 2009 @@ -98,18 +98,20 @@ def testAuthAllowedEdit(self): self.db.setCurrentUser('admin') try: - self.server.set('user2', 'realname=someone') - except Unauthorised, err: - self.fail('raised %s'%err) + try: + self.server.set('user2', 'realname=someone') + except Unauthorised, err: + self.fail('raised %s'%err) finally: self.db.setCurrentUser('joe') def testAuthAllowedCreate(self): self.db.setCurrentUser('admin') try: - self.server.create('user', 'username=blah') - except Unauthorised, err: - self.fail('raised %s'%err) + try: + self.server.create('user', 'username=blah') + except Unauthorised, err: + self.fail('raised %s'%err) finally: self.db.setCurrentUser('joe') From python-checkins at python.org Fri Nov 27 14:18:35 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 27 Nov 2009 13:18:35 -0000 Subject: [Python-checkins] r76546 - in python/trunk: Doc/library/ftplib.rst Lib/ftplib.py Lib/test/test_ftplib.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 27 14:18:34 2009 New Revision: 76546 Log: Issue #6845: Add restart support for binary upload in ftplib. The `storbinary()` method of FTP and FTP_TLS objects gains an optional `rest` argument. Patch by Pablo Mouzo. (note: the patch also adds a test for the rest argument in retrbinary()) Modified: python/trunk/Doc/library/ftplib.rst python/trunk/Lib/ftplib.py python/trunk/Lib/test/test_ftplib.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/ftplib.rst ============================================================================== --- python/trunk/Doc/library/ftplib.rst (original) +++ python/trunk/Doc/library/ftplib.rst Fri Nov 27 14:18:34 2009 @@ -233,14 +233,15 @@ it is on by default.) -.. method:: FTP.storbinary(command, file[, blocksize, callback]) +.. method:: FTP.storbinary(command, file[, blocksize, callback, rest]) Store a file in binary transfer mode. *command* should be an appropriate ``STOR`` command: ``"STOR filename"``. *file* is an open file object which is read until EOF using its :meth:`read` method in blocks of size *blocksize* to provide the data to be stored. The *blocksize* argument defaults to 8192. *callback* is an optional single parameter callable that is called - on each block of data after it is sent. + on each block of data after it is sent. *rest* means the same thing as in + the :meth:`transfercmd` method. .. versionchanged:: 2.1 default for *blocksize* added. @@ -248,6 +249,8 @@ .. versionchanged:: 2.6 *callback* parameter added. + .. versionchanged:: 2.7 + *rest* parameter added. .. method:: FTP.storlines(command, file[, callback]) Modified: python/trunk/Lib/ftplib.py ============================================================================== --- python/trunk/Lib/ftplib.py (original) +++ python/trunk/Lib/ftplib.py Fri Nov 27 14:18:34 2009 @@ -431,7 +431,7 @@ conn.close() return self.voidresp() - def storbinary(self, cmd, fp, blocksize=8192, callback=None): + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): """Store a file in binary mode. A new port is created for you. Args: @@ -441,12 +441,13 @@ the connection at once. [default: 8192] callback: An optional single parameter callable that is called on on each block of data after it is sent. [default: None] + rest: Passed to transfercmd(). [default: None] Returns: The response code. """ self.voidcmd('TYPE I') - conn = self.transfercmd(cmd) + conn = self.transfercmd(cmd, rest) while 1: buf = fp.read(blocksize) if not buf: break @@ -712,9 +713,9 @@ conn.close() return self.voidresp() - def storbinary(self, cmd, fp, blocksize=8192, callback=None): + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): self.voidcmd('TYPE I') - conn = self.transfercmd(cmd) + conn = self.transfercmd(cmd, rest) try: while 1: buf = fp.read(blocksize) Modified: python/trunk/Lib/test/test_ftplib.py ============================================================================== --- python/trunk/Lib/test/test_ftplib.py (original) +++ python/trunk/Lib/test/test_ftplib.py Fri Nov 27 14:18:34 2009 @@ -55,6 +55,7 @@ self.last_received_cmd = None self.last_received_data = '' self.next_response = '' + self.rest = None self.push('220 welcome') def collect_incoming_data(self, data): @@ -168,10 +169,19 @@ def cmd_stor(self, arg): self.push('125 stor ok') + def cmd_rest(self, arg): + self.rest = arg + self.push('350 rest ok') + def cmd_retr(self, arg): self.push('125 retr ok') - self.dtp.push(RETR_DATA) + if self.rest is not None: + offset = int(self.rest) + else: + offset = 0 + self.dtp.push(RETR_DATA[offset:]) self.dtp.close_when_done() + self.rest = None def cmd_list(self, arg): self.push('125 list ok') @@ -444,6 +454,15 @@ self.client.retrbinary('retr', received.append) self.assertEqual(''.join(received), RETR_DATA) + def test_retrbinary_rest(self): + for rest in (0, 10, 20): + received = [] + self.client.retrbinary('retr', received.append, rest=rest) + self.assertEqual(''.join(received), RETR_DATA[rest:], + msg='rest test case %d %d %d' % (rest, + len(''.join(received)), + len(RETR_DATA[rest:]))) + def test_retrlines(self): received = [] self.client.retrlines('retr', received.append) @@ -459,6 +478,13 @@ self.client.storbinary('stor', f, callback=lambda x: flag.append(None)) self.assertTrue(flag) + def test_storbinary_rest(self): + f = StringIO.StringIO(RETR_DATA) + for r in (30, '30'): + f.seek(0) + self.client.storbinary('stor', f, rest=r) + self.assertEqual(self.server.handler.rest, str(r)) + def test_storlines(self): f = StringIO.StringIO(RETR_DATA.replace('\r\n', '\n')) self.client.storlines('stor', f) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 27 14:18:34 2009 @@ -483,6 +483,10 @@ Library ------- +- Issue #6845: Add restart support for binary upload in ftplib. The + `storbinary()` method of FTP and FTP_TLS objects gains an optional `rest` + argument. Patch by Pablo Mouzo. + - Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` method returning the total number of seconds in the duration. Patch by Brian Quinlan. From python-checkins at python.org Fri Nov 27 14:23:26 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 27 Nov 2009 13:23:26 -0000 Subject: [Python-checkins] r76547 - in python/branches/py3k: Doc/library/ftplib.rst Lib/ftplib.py Lib/test/test_ftplib.py Misc/NEWS Message-ID: Author: antoine.pitrou Date: Fri Nov 27 14:23:26 2009 New Revision: 76547 Log: Merged revisions 76546 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76546 | antoine.pitrou | 2009-11-27 14:18:34 +0100 (ven., 27 nov. 2009) | 7 lines Issue #6845: Add restart support for binary upload in ftplib. The `storbinary()` method of FTP and FTP_TLS objects gains an optional `rest` argument. Patch by Pablo Mouzo. (note: the patch also adds a test for the rest argument in retrbinary()) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/ftplib.rst python/branches/py3k/Lib/ftplib.py python/branches/py3k/Lib/test/test_ftplib.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/ftplib.rst ============================================================================== --- python/branches/py3k/Doc/library/ftplib.rst (original) +++ python/branches/py3k/Doc/library/ftplib.rst Fri Nov 27 14:23:26 2009 @@ -226,14 +226,18 @@ Passive mode is on by default. -.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None) +.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None) Store a file in binary transfer mode. *cmd* should be an appropriate ``STOR`` command: ``"STOR filename"``. *file* is an open file object which is read until EOF using its :meth:`read` method in blocks of size *blocksize* to provide the data to be stored. The *blocksize* argument defaults to 8192. *callback* is an optional single parameter callable that is called - on each block of data after it is sent. + on each block of data after it is sent. *rest* means the same thing as in + the :meth:`transfercmd` method. + + .. versionchanged:: 3.2 + *rest* parameter added. .. method:: FTP.storlines(cmd, file, callback=None) Modified: python/branches/py3k/Lib/ftplib.py ============================================================================== --- python/branches/py3k/Lib/ftplib.py (original) +++ python/branches/py3k/Lib/ftplib.py Fri Nov 27 14:23:26 2009 @@ -433,7 +433,7 @@ conn.close() return self.voidresp() - def storbinary(self, cmd, fp, blocksize=8192, callback=None): + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): """Store a file in binary mode. A new port is created for you. Args: @@ -443,12 +443,13 @@ the connection at once. [default: 8192] callback: An optional single parameter callable that is called on on each block of data after it is sent. [default: None] + rest: Passed to transfercmd(). [default: None] Returns: The response code. """ self.voidcmd('TYPE I') - conn = self.transfercmd(cmd) + conn = self.transfercmd(cmd, rest) while 1: buf = fp.read(blocksize) if not buf: break @@ -714,9 +715,9 @@ conn.close() return self.voidresp() - def storbinary(self, cmd, fp, blocksize=8192, callback=None): + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): self.voidcmd('TYPE I') - conn = self.transfercmd(cmd) + conn = self.transfercmd(cmd, rest) try: while 1: buf = fp.read(blocksize) Modified: python/branches/py3k/Lib/test/test_ftplib.py ============================================================================== --- python/branches/py3k/Lib/test/test_ftplib.py (original) +++ python/branches/py3k/Lib/test/test_ftplib.py Fri Nov 27 14:23:26 2009 @@ -57,6 +57,7 @@ self.last_received_cmd = None self.last_received_data = '' self.next_response = '' + self.rest = None self.push('220 welcome') def collect_incoming_data(self, data): @@ -170,10 +171,19 @@ def cmd_stor(self, arg): self.push('125 stor ok') + def cmd_rest(self, arg): + self.rest = arg + self.push('350 rest ok') + def cmd_retr(self, arg): self.push('125 retr ok') - self.dtp.push(RETR_DATA) + if self.rest is not None: + offset = int(self.rest) + else: + offset = 0 + self.dtp.push(RETR_DATA[offset:]) self.dtp.close_when_done() + self.rest = None def cmd_list(self, arg): self.push('125 list ok') @@ -450,6 +460,17 @@ self.client.retrbinary('retr', callback) self.assertEqual(''.join(received), RETR_DATA) + def test_retrbinary_rest(self): + def callback(data): + received.append(data.decode('ascii')) + for rest in (0, 10, 20): + received = [] + self.client.retrbinary('retr', callback, rest=rest) + self.assertEqual(''.join(received), RETR_DATA[rest:], + msg='rest test case %d %d %d' % (rest, + len(''.join(received)), + len(RETR_DATA[rest:]))) + def test_retrlines(self): received = [] self.client.retrlines('retr', received.append) @@ -465,6 +486,13 @@ self.client.storbinary('stor', f, callback=lambda x: flag.append(None)) self.assertTrue(flag) + def test_storbinary_rest(self): + f = io.BytesIO(RETR_DATA.replace('\r\n', '\n').encode('ascii')) + for r in (30, '30'): + f.seek(0) + self.client.storbinary('stor', f, rest=r) + self.assertEqual(self.server.handler.rest, str(r)) + def test_storlines(self): f = io.BytesIO(RETR_DATA.replace('\r\n', '\n').encode('ascii')) self.client.storlines('stor', f) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Nov 27 14:23:26 2009 @@ -140,6 +140,10 @@ Library ------- +- Issue #6845: Add restart support for binary upload in ftplib. The + `storbinary()` method of FTP and FTP_TLS objects gains an optional `rest` + argument. Patch by Pablo Mouzo. + - Issue #5788: `datetime.timedelta` objects get a new `total_seconds()` method returning the total number of seconds in the duration. Patch by Brian Quinlan. From python-checkins at python.org Fri Nov 27 14:24:29 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 27 Nov 2009 13:24:29 -0000 Subject: [Python-checkins] r76548 - python/trunk/Misc/ACKS Message-ID: Author: antoine.pitrou Date: Fri Nov 27 14:24:29 2009 New Revision: 76548 Log: Add ACKS entry for Pablo Mouzo Modified: python/trunk/Misc/ACKS Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Fri Nov 27 14:24:29 2009 @@ -512,6 +512,7 @@ Paul Moore Derek Morr James A Morrison +Pablo Mouzo Sjoerd Mullender Sape Mullender Michael Muller From python-checkins at python.org Fri Nov 27 14:25:31 2009 From: python-checkins at python.org (antoine.pitrou) Date: Fri, 27 Nov 2009 13:25:31 -0000 Subject: [Python-checkins] r76549 - in python/branches/py3k: Misc/ACKS Message-ID: Author: antoine.pitrou Date: Fri Nov 27 14:25:31 2009 New Revision: 76549 Log: Merged revisions 76548 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76548 | antoine.pitrou | 2009-11-27 14:24:29 +0100 (ven., 27 nov. 2009) | 3 lines Add ACKS entry for Pablo Mouzo ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/ACKS Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Fri Nov 27 14:25:31 2009 @@ -516,6 +516,7 @@ Paul Moore Derek Morr James A Morrison +Pablo Mouzo Sjoerd Mullender Sape Mullender Michael Muller From python-checkins at python.org Fri Nov 27 14:56:02 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 27 Nov 2009 13:56:02 -0000 Subject: [Python-checkins] r76550 - in python/trunk: Doc/library/os.rst Lib/test/test_posix.py Misc/NEWS Modules/posixmodule.c configure configure.in pyconfig.h.in Message-ID: Author: martin.v.loewis Date: Fri Nov 27 14:56:01 2009 New Revision: 76550 Log: Issue #6508: Add posix.{getresuid,getresgid,setresuid,setresgid}. Modified: python/trunk/Doc/library/os.rst python/trunk/Lib/test/test_posix.py python/trunk/Misc/NEWS python/trunk/Modules/posixmodule.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in Modified: python/trunk/Doc/library/os.rst ============================================================================== --- python/trunk/Doc/library/os.rst (original) +++ python/trunk/Doc/library/os.rst Fri Nov 27 14:56:01 2009 @@ -173,6 +173,19 @@ Return the parent's process id. Availability: Unix. +.. function:: getresgid() + + Return a tuple (ruid, euid, suid) denoting the current process's + real, effective, and saved user ids. Availability: Unix. + + .. versionadded:: 2.7/3.2 + +.. function:: getresuid() + + Return a tuple (rgid, egid, sgid) denoting the current process's + real, effective, and saved user ids. Availability: Unix. + + .. versionadded:: 2.7/3.2 .. function:: getuid() @@ -247,14 +260,27 @@ for the semantics. Availability: Unix. -.. function:: setreuid(ruid, euid) +.. function:: setregid(rgid, egid) - Set the current process's real and effective user ids. Availability: Unix. + Set the current process's real and effective group ids. Availability: Unix. +.. function:: setresgid(rgid, egid, sgid) -.. function:: setregid(rgid, egid) + Set the current process's real, effective, and saved group ids. + Availability: Unix. - Set the current process's real and effective group ids. Availability: Unix. + .. versionadded:: 2.7/3.2 + +.. function:: setresuid(ruid, euid, suid) + + Set the current process's real, effective, and saved user ids. + Availibility: Unix. + + .. versionadded:: 2.7/3.2 + +.. function:: setreuid(ruid, euid) + + Set the current process's real and effective user ids. Availability: Unix. .. function:: getsid(pid) Modified: python/trunk/Lib/test/test_posix.py ============================================================================== --- python/trunk/Lib/test/test_posix.py (original) +++ python/trunk/Lib/test/test_posix.py Fri Nov 27 14:56:01 2009 @@ -41,6 +41,48 @@ posix_func() self.assertRaises(TypeError, posix_func, 1) + if hasattr(posix, 'getresuid'): + def test_getresuid(self): + user_ids = posix.getresuid() + self.assertEqual(len(user_ids), 3) + for val in user_ids: + self.assertGreaterEqual(val, 0) + + if hasattr(posix, 'getresgid'): + def test_getresgid(self): + group_ids = posix.getresgid() + self.assertEqual(len(group_ids), 3) + for val in group_ids: + self.assertGreaterEqual(val, 0) + + if hasattr(posix, 'setresuid'): + def test_setresuid(self): + current_user_ids = posix.getresuid() + self.assertIsNone(posix.setresuid(*current_user_ids)) + # -1 means don't change that value. + self.assertIsNone(posix.setresuid(-1, -1, -1)) + + def test_setresuid_exception(self): + # Don't do this test if someone is silly enough to run us as root. + current_user_ids = posix.getresuid() + if 0 not in current_user_ids: + new_user_ids = (current_user_ids[0]+1, -1, -1) + self.assertRaises(OSError, posix.setresuid, *new_user_ids) + + if hasattr(posix, 'setresgid'): + def test_setresgid(self): + current_group_ids = posix.getresgid() + self.assertIsNone(posix.setresgid(*current_group_ids)) + # -1 means don't change that value. + self.assertIsNone(posix.setresgid(-1, -1, -1)) + + def test_setresgid_exception(self): + # Don't do this test if someone is silly enough to run us as root. + current_group_ids = posix.getresgid() + if 0 not in current_group_ids: + new_group_ids = (current_group_ids[0]+1, -1, -1) + self.assertRaises(OSError, posix.setresgid, *new_group_ids) + def test_statvfs(self): if hasattr(posix, 'statvfs'): self.assertTrue(posix.statvfs(os.curdir)) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 27 14:56:01 2009 @@ -1589,6 +1589,8 @@ Extension Modules ----------------- +- Issue #6508: Add posix.{getresuid,getresgid,setresuid,setresgid}. + - Issue #7078: Set struct.__doc__ from _struct.__doc__. - Issue #3366: Add gamma function to math module. Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Fri Nov 27 14:56:01 2009 @@ -8386,6 +8386,82 @@ } #endif +#ifdef HAVE_SETRESUID +PyDoc_STRVAR(posix_setresuid__doc__, +"setresuid(ruid, euid, suid)\n\n\ +Set the current process's real, effective, and saved user ids."); + +static PyObject* +posix_setresuid (PyObject *self, PyObject *args) +{ + /* We assume uid_t is no larger than a long. */ + long ruid, euid, suid; + if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid)) + return NULL; + if (setresuid(ruid, euid, suid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif + +#ifdef HAVE_SETRESGID +PyDoc_STRVAR(posix_setresgid__doc__, +"setresgid(rgid, egid, sgid)\n\n\ +Set the current process's real, effective, and saved group ids."); + +static PyObject* +posix_setresgid (PyObject *self, PyObject *args) +{ + /* We assume uid_t is no larger than a long. */ + long rgid, egid, sgid; + if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid)) + return NULL; + if (setresgid(rgid, egid, sgid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif + +#ifdef HAVE_GETRESUID +PyDoc_STRVAR(posix_getresuid__doc__, +"getresuid() -> (ruid, euid, suid)\n\n\ +Get tuple of the current process's real, effective, and saved user ids."); + +static PyObject* +posix_getresuid (PyObject *self, PyObject *noargs) +{ + uid_t ruid, euid, suid; + long l_ruid, l_euid, l_suid; + if (getresuid(&ruid, &euid, &suid) < 0) + return posix_error(); + /* Force the values into long's as we don't know the size of uid_t. */ + l_ruid = ruid; + l_euid = euid; + l_suid = suid; + return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid); +} +#endif + +#ifdef HAVE_GETRESGID +PyDoc_STRVAR(posix_getresgid__doc__, +"getresgid() -> (rgid, egid, sgid)\n\n\ +Get tuple of the current process's real, effective, and saved user ids."); + +static PyObject* +posix_getresgid (PyObject *self, PyObject *noargs) +{ + uid_t rgid, egid, sgid; + long l_rgid, l_egid, l_sgid; + if (getresgid(&rgid, &egid, &sgid) < 0) + return posix_error(); + /* Force the values into long's as we don't know the size of uid_t. */ + l_rgid = rgid; + l_egid = egid; + l_sgid = sgid; + return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid); +} +#endif + static PyMethodDef posix_methods[] = { {"access", posix_access, METH_VARARGS, posix_access__doc__}, #ifdef HAVE_TTYNAME @@ -8696,6 +8772,19 @@ #ifdef __VMS {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__}, #endif +#ifdef HAVE_SETRESUID + {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, +#endif +#ifdef HAVE_SETRESGID + {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, +#endif +#ifdef HAVE_GETRESUID + {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, +#endif +#ifdef HAVE_GETRESGID + {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, +#endif + {NULL, NULL} /* Sentinel */ }; Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Fri Nov 27 14:56:01 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76403 . +# From configure.in Revision: 76432 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -17882,16 +17882,31 @@ + + + + + + + + + + + + + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ - getpriority getpwent getspnam getspent getsid getwd \ + getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ + setlocale setregid setreuid setresuid setresgid \ + setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 wcscoll _getpty Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Fri Nov 27 14:56:01 2009 @@ -2546,13 +2546,15 @@ AC_CHECK_FUNCS(alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ - getpriority getpwent getspnam getspent getsid getwd \ + getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ + setlocale setregid setreuid setresuid setresgid \ + setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 wcscoll _getpty) Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Fri Nov 27 14:56:01 2009 @@ -316,6 +316,12 @@ /* Define to 1 if you have the `getpwent' function. */ #undef HAVE_GETPWENT +/* Define to 1 if you have the `getresgid' function. */ +#undef HAVE_GETRESGID + +/* Define to 1 if you have the `getresuid' function. */ +#undef HAVE_GETRESUID + /* Define to 1 if you have the `getsid' function. */ #undef HAVE_GETSID @@ -580,6 +586,12 @@ /* Define to 1 if you have the `setregid' function. */ #undef HAVE_SETREGID +/* Define to 1 if you have the `setresgid' function. */ +#undef HAVE_SETRESGID + +/* Define to 1 if you have the `setresuid' function. */ +#undef HAVE_SETRESUID + /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID From python-checkins at python.org Fri Nov 27 15:03:36 2009 From: python-checkins at python.org (vinay.sajip) Date: Fri, 27 Nov 2009 14:03:36 -0000 Subject: [Python-checkins] r76551 - in python: branches/py3k/Lib/logging/__init__.py branches/py3k/Misc/NEWS branches/release26-maint/Lib/logging/__init__.py branches/release26-maint/Misc/NEWS trunk/Lib/logging/__init__.py trunk/Misc/NEWS Message-ID: Author: vinay.sajip Date: Fri Nov 27 15:03:36 2009 New Revision: 76551 Log: Issue #7403: Fixed possible race condition in lock creation. Modified: python/branches/py3k/Lib/logging/__init__.py python/branches/py3k/Misc/NEWS python/branches/release26-maint/Lib/logging/__init__.py python/branches/release26-maint/Misc/NEWS python/trunk/Lib/logging/__init__.py python/trunk/Misc/NEWS Modified: python/branches/py3k/Lib/logging/__init__.py ============================================================================== --- python/branches/py3k/Lib/logging/__init__.py (original) +++ python/branches/py3k/Lib/logging/__init__.py Fri Nov 27 15:03:36 2009 @@ -199,7 +199,11 @@ #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # -_lock = None +if thread: + _lock = threading.RLock() +else: + _lock = None + def _acquireLock(): """ @@ -207,9 +211,6 @@ This should be released with _releaseLock(). """ - global _lock - if (not _lock) and thread: - _lock = threading.RLock() if _lock: _lock.acquire() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Nov 27 15:03:36 2009 @@ -140,6 +140,8 @@ Library ------- +- Issue #7403: logging: Fixed possible race condition in lock creation. + - Issue #6845: Add restart support for binary upload in ftplib. The `storbinary()` method of FTP and FTP_TLS objects gains an optional `rest` argument. Patch by Pablo Mouzo. Modified: python/branches/release26-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/logging/__init__.py (original) +++ python/branches/release26-maint/Lib/logging/__init__.py Fri Nov 27 15:03:36 2009 @@ -186,7 +186,10 @@ #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # -_lock = None +if thread: + _lock = threading.RLock() +else: + _lock = None def _acquireLock(): """ @@ -194,9 +197,6 @@ This should be released with _releaseLock(). """ - global _lock - if (not _lock) and thread: - _lock = threading.RLock() if _lock: _lock.acquire() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Nov 27 15:03:36 2009 @@ -33,6 +33,8 @@ Library ------- +- Issue #7403: logging: Fixed possible race condition in lock creation. + - Issue #7341: Close the internal file object in the TarFile constructor in case of an error. Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Fri Nov 27 15:03:36 2009 @@ -202,7 +202,10 @@ #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # -_lock = None +if thread: + _lock = threading.RLock() +else: + _lock = None def _acquireLock(): """ @@ -210,9 +213,6 @@ This should be released with _releaseLock(). """ - global _lock - if (not _lock) and thread: - _lock = threading.RLock() if _lock: _lock.acquire() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Nov 27 15:03:36 2009 @@ -483,6 +483,8 @@ Library ------- +- Issue #7403: logging: Fixed possible race condition in lock creation. + - Issue #6845: Add restart support for binary upload in ftplib. The `storbinary()` method of FTP and FTP_TLS objects gains an optional `rest` argument. Patch by Pablo Mouzo. From python-checkins at python.org Fri Nov 27 15:09:49 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 27 Nov 2009 14:09:49 -0000 Subject: [Python-checkins] r76552 - in python/branches/py3k: Doc/library/os.rst Lib/test/test_posix.py Misc/NEWS Modules/posixmodule.c configure configure.in pyconfig.h.in Message-ID: Author: martin.v.loewis Date: Fri Nov 27 15:09:49 2009 New Revision: 76552 Log: Merged revisions 76550 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76550 | martin.v.loewis | 2009-11-27 14:56:01 +0100 (Fr, 27 Nov 2009) | 2 lines Issue #6508: Add posix.{getresuid,getresgid,setresuid,setresgid}. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/os.rst python/branches/py3k/Lib/test/test_posix.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/posixmodule.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Fri Nov 27 15:09:49 2009 @@ -196,6 +196,19 @@ Return the parent's process id. Availability: Unix. +.. function:: getresgid() + + Return a tuple (ruid, euid, suid) denoting the current process's + real, effective, and saved user ids. Availability: Unix. + + .. versionadded:: 2.7/3.2 + +.. function:: getresuid() + + Return a tuple (rgid, egid, sgid) denoting the current process's + real, effective, and saved user ids. Availability: Unix. + + .. versionadded:: 2.7/3.2 .. function:: getuid() @@ -267,14 +280,27 @@ for the semantics. Availability: Unix. -.. function:: setreuid(ruid, euid) +.. function:: setregid(rgid, egid) - Set the current process's real and effective user ids. Availability: Unix. + Set the current process's real and effective group ids. Availability: Unix. +.. function:: setresgid(rgid, egid, sgid) -.. function:: setregid(rgid, egid) + Set the current process's real, effective, and saved group ids. + Availability: Unix. - Set the current process's real and effective group ids. Availability: Unix. + .. versionadded:: 2.7/3.2 + +.. function:: setresuid(ruid, euid, suid) + + Set the current process's real, effective, and saved user ids. + Availibility: Unix. + + .. versionadded:: 2.7/3.2 + +.. function:: setreuid(ruid, euid) + + Set the current process's real and effective user ids. Availability: Unix. .. function:: getsid(pid) Modified: python/branches/py3k/Lib/test/test_posix.py ============================================================================== --- python/branches/py3k/Lib/test/test_posix.py (original) +++ python/branches/py3k/Lib/test/test_posix.py Fri Nov 27 15:09:49 2009 @@ -40,6 +40,48 @@ posix_func() self.assertRaises(TypeError, posix_func, 1) + if hasattr(posix, 'getresuid'): + def test_getresuid(self): + user_ids = posix.getresuid() + self.assertEqual(len(user_ids), 3) + for val in user_ids: + self.assertGreaterEqual(val, 0) + + if hasattr(posix, 'getresgid'): + def test_getresgid(self): + group_ids = posix.getresgid() + self.assertEqual(len(group_ids), 3) + for val in group_ids: + self.assertGreaterEqual(val, 0) + + if hasattr(posix, 'setresuid'): + def test_setresuid(self): + current_user_ids = posix.getresuid() + self.assertIsNone(posix.setresuid(*current_user_ids)) + # -1 means don't change that value. + self.assertIsNone(posix.setresuid(-1, -1, -1)) + + def test_setresuid_exception(self): + # Don't do this test if someone is silly enough to run us as root. + current_user_ids = posix.getresuid() + if 0 not in current_user_ids: + new_user_ids = (current_user_ids[0]+1, -1, -1) + self.assertRaises(OSError, posix.setresuid, *new_user_ids) + + if hasattr(posix, 'setresgid'): + def test_setresgid(self): + current_group_ids = posix.getresgid() + self.assertIsNone(posix.setresgid(*current_group_ids)) + # -1 means don't change that value. + self.assertIsNone(posix.setresgid(-1, -1, -1)) + + def test_setresgid_exception(self): + # Don't do this test if someone is silly enough to run us as root. + current_group_ids = posix.getresgid() + if 0 not in current_group_ids: + new_group_ids = (current_group_ids[0]+1, -1, -1) + self.assertRaises(OSError, posix.setresgid, *new_group_ids) + def test_statvfs(self): if hasattr(posix, 'statvfs'): self.assertTrue(posix.statvfs(os.curdir)) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Nov 27 15:09:49 2009 @@ -388,6 +388,8 @@ Extension Modules ----------------- +- Issue #6508: Add posix.{getresuid,getresgid,setresuid,setresgid}. + - Issue #7078: Set struct.__doc__ from _struct.__doc__. - Issue #3366: Add gamma function to math module. Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Fri Nov 27 15:09:49 2009 @@ -6953,6 +6953,82 @@ } #endif +#ifdef HAVE_SETRESUID +PyDoc_STRVAR(posix_setresuid__doc__, +"setresuid(ruid, euid, suid)\n\n\ +Set the current process's real, effective, and saved user ids."); + +static PyObject* +posix_setresuid (PyObject *self, PyObject *args) +{ + /* We assume uid_t is no larger than a long. */ + long ruid, euid, suid; + if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid)) + return NULL; + if (setresuid(ruid, euid, suid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif + +#ifdef HAVE_SETRESGID +PyDoc_STRVAR(posix_setresgid__doc__, +"setresgid(rgid, egid, sgid)\n\n\ +Set the current process's real, effective, and saved group ids."); + +static PyObject* +posix_setresgid (PyObject *self, PyObject *args) +{ + /* We assume uid_t is no larger than a long. */ + long rgid, egid, sgid; + if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid)) + return NULL; + if (setresgid(rgid, egid, sgid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif + +#ifdef HAVE_GETRESUID +PyDoc_STRVAR(posix_getresuid__doc__, +"getresuid() -> (ruid, euid, suid)\n\n\ +Get tuple of the current process's real, effective, and saved user ids."); + +static PyObject* +posix_getresuid (PyObject *self, PyObject *noargs) +{ + uid_t ruid, euid, suid; + long l_ruid, l_euid, l_suid; + if (getresuid(&ruid, &euid, &suid) < 0) + return posix_error(); + /* Force the values into long's as we don't know the size of uid_t. */ + l_ruid = ruid; + l_euid = euid; + l_suid = suid; + return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid); +} +#endif + +#ifdef HAVE_GETRESGID +PyDoc_STRVAR(posix_getresgid__doc__, +"getresgid() -> (rgid, egid, sgid)\n\n\ +Get tuple of the current process's real, effective, and saved user ids."); + +static PyObject* +posix_getresgid (PyObject *self, PyObject *noargs) +{ + uid_t rgid, egid, sgid; + long l_rgid, l_egid, l_sgid; + if (getresgid(&rgid, &egid, &sgid) < 0) + return posix_error(); + /* Force the values into long's as we don't know the size of uid_t. */ + l_rgid = rgid; + l_egid = egid; + l_sgid = sgid; + return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid); +} +#endif + static PyMethodDef posix_methods[] = { {"access", posix_access, METH_VARARGS, posix_access__doc__}, #ifdef HAVE_TTYNAME @@ -7242,6 +7318,19 @@ #ifdef __VMS {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__}, #endif +#ifdef HAVE_SETRESUID + {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, +#endif +#ifdef HAVE_SETRESGID + {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, +#endif +#ifdef HAVE_GETRESUID + {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, +#endif +#ifdef HAVE_GETRESGID + {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, +#endif + {NULL, NULL} /* Sentinel */ }; Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Fri Nov 27 15:09:49 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76328 . +# From configure.in Revision: 76405 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -3800,7 +3800,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f -r conftest* +rm -f conftest* @@ -5338,7 +5338,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -5359,7 +5359,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6457,7 +6457,7 @@ fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -6987,7 +6987,7 @@ else ac_cv_type_uid_t=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -15529,7 +15529,7 @@ else unistd_defines_pthreads=no fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -16827,7 +16827,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f -r conftest* +rm -f conftest* ;; kame) @@ -16850,7 +16850,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-glibc) @@ -16871,7 +16871,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-inet6) @@ -16909,7 +16909,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; v6d) @@ -16932,7 +16932,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f -r conftest* +rm -f conftest* ;; zeta) @@ -16954,7 +16954,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; esac @@ -17375,17 +17375,21 @@ + + + + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ - getpriority getpwent getspnam getspent getsid getwd \ + getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ - setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ - sigaction siginterrupt sigrelse strftime strlcpy \ + setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ + sigaction siginterrupt sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty @@ -25044,7 +25048,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -25063,7 +25067,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi @@ -25333,7 +25337,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Fri Nov 27 15:09:49 2009 @@ -2417,14 +2417,14 @@ AC_CHECK_FUNCS(alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ - getpriority getpwent getspnam getspent getsid getwd \ + getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ - setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ - sigaction siginterrupt sigrelse strftime strlcpy \ + setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setuid setvbuf \ + sigaction siginterrupt sigrelse snprintf strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unsetenv utimes waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm _getpty) Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Fri Nov 27 15:09:49 2009 @@ -314,6 +314,12 @@ /* Define to 1 if you have the `getpwent' function. */ #undef HAVE_GETPWENT +/* Define to 1 if you have the `getresgid' function. */ +#undef HAVE_GETRESGID + +/* Define to 1 if you have the `getresuid' function. */ +#undef HAVE_GETRESUID + /* Define to 1 if you have the `getsid' function. */ #undef HAVE_GETSID @@ -578,6 +584,12 @@ /* Define to 1 if you have the `setregid' function. */ #undef HAVE_SETREGID +/* Define to 1 if you have the `setresgid' function. */ +#undef HAVE_SETRESGID + +/* Define to 1 if you have the `setresuid' function. */ +#undef HAVE_SETRESUID + /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID From python-checkins at python.org Fri Nov 27 16:34:35 2009 From: python-checkins at python.org (vinay.sajip) Date: Fri, 27 Nov 2009 15:34:35 -0000 Subject: [Python-checkins] r76554 - in python/branches/release25-maint: Lib/logging/__init__.py Misc/NEWS Message-ID: Author: vinay.sajip Date: Fri Nov 27 16:34:35 2009 New Revision: 76554 Log: Issue #7403: logging: Fixed possible race condition in lock creation. Modified: python/branches/release25-maint/Lib/logging/__init__.py python/branches/release25-maint/Misc/NEWS Modified: python/branches/release25-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release25-maint/Lib/logging/__init__.py (original) +++ python/branches/release25-maint/Lib/logging/__init__.py Fri Nov 27 16:34:35 2009 @@ -176,7 +176,10 @@ #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # -_lock = None +if thread: + _lock = threading.RLock() +else: + _lock = None def _acquireLock(): """ @@ -184,9 +187,6 @@ This should be released with _releaseLock(). """ - global _lock - if (not _lock) and thread: - _lock = threading.RLock() if _lock: _lock.acquire() Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Fri Nov 27 16:34:35 2009 @@ -18,6 +18,8 @@ Library ------- +- Issue #7403: logging: Fixed possible race condition in lock creation. + - Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop forever on incomplete input. That caused tarfile.open() to hang when used with mode 'r' or 'r:bz2' and a fileobj argument that contained no data or From python-checkins at python.org Fri Nov 27 16:36:32 2009 From: python-checkins at python.org (vinay.sajip) Date: Fri, 27 Nov 2009 15:36:32 -0000 Subject: [Python-checkins] r76555 - in python/branches/release24-maint: Lib/logging/__init__.py Misc/NEWS Message-ID: Author: vinay.sajip Date: Fri Nov 27 16:36:32 2009 New Revision: 76555 Log: Issue #7403: logging: Fixed possible race condition in lock creation. Modified: python/branches/release24-maint/Lib/logging/__init__.py python/branches/release24-maint/Misc/NEWS Modified: python/branches/release24-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release24-maint/Lib/logging/__init__.py (original) +++ python/branches/release24-maint/Lib/logging/__init__.py Fri Nov 27 16:36:32 2009 @@ -166,7 +166,10 @@ #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # -_lock = None +if thread: + _lock = threading.RLock() +else: + _lock = None def _acquireLock(): """ @@ -174,9 +177,6 @@ This should be released with _releaseLock(). """ - global _lock - if (not _lock) and thread: - _lock = threading.RLock() if _lock: _lock.acquire() Modified: python/branches/release24-maint/Misc/NEWS ============================================================================== --- python/branches/release24-maint/Misc/NEWS (original) +++ python/branches/release24-maint/Misc/NEWS Fri Nov 27 16:36:32 2009 @@ -9,6 +9,11 @@ *Release date: XX-XXX-2009* +Library +------- + +- Issue #7403: logging: Fixed possible race condition in lock creation. + What's New in Python 2.4.6? =========================== From python-checkins at python.org Fri Nov 27 18:51:12 2009 From: python-checkins at python.org (gregory.p.smith) Date: Fri, 27 Nov 2009 17:51:12 -0000 Subject: [Python-checkins] r76556 - python/trunk/Doc/library/os.rst Message-ID: Author: gregory.p.smith Date: Fri Nov 27 18:51:12 2009 New Revision: 76556 Log: fix typo Modified: python/trunk/Doc/library/os.rst Modified: python/trunk/Doc/library/os.rst ============================================================================== --- python/trunk/Doc/library/os.rst (original) +++ python/trunk/Doc/library/os.rst Fri Nov 27 18:51:12 2009 @@ -173,14 +173,14 @@ Return the parent's process id. Availability: Unix. -.. function:: getresgid() +.. function:: getresuid() Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. Availability: Unix. .. versionadded:: 2.7/3.2 -.. function:: getresuid() +.. function:: getresgid() Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved user ids. Availability: Unix. From python-checkins at python.org Fri Nov 27 18:54:18 2009 From: python-checkins at python.org (gregory.p.smith) Date: Fri, 27 Nov 2009 17:54:18 -0000 Subject: [Python-checkins] r76557 - in python/branches/py3k: Doc/library/os.rst Message-ID: Author: gregory.p.smith Date: Fri Nov 27 18:54:17 2009 New Revision: 76557 Log: Merged revisions 76556 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76556 | gregory.p.smith | 2009-11-27 09:51:12 -0800 (Fri, 27 Nov 2009) | 2 lines fix typo ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/os.rst Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Fri Nov 27 18:54:17 2009 @@ -196,14 +196,14 @@ Return the parent's process id. Availability: Unix. -.. function:: getresgid() +.. function:: getresuid() Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. Availability: Unix. .. versionadded:: 2.7/3.2 -.. function:: getresuid() +.. function:: getresgid() Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved user ids. Availability: Unix. From nnorwitz at gmail.com Fri Nov 27 22:14:23 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 27 Nov 2009 16:14:23 -0500 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20091127211423.GA25007@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn fetching http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml ... fetching http://people.freebsd.org/~perky/i18n/EUC-CN.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT ... test_codecmaps_hk fetching http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT ... test_codecmaps_jp fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT ... fetching http://people.freebsd.org/~perky/i18n/EUC-JISX0213.TXT ... fetching http://people.freebsd.org/~perky/i18n/EUC-JP.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT ... fetching http://people.freebsd.org/~perky/i18n/SHIFT_JISX0213.TXT ... test_codecmaps_kr fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT ... fetching http://people.freebsd.org/~perky/i18n/EUC-KR.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT ... test_codecmaps_tw fetching http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ... fetching http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT ... test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization fetching http://www.unicode.org/Public/5.1.0/ucd/NormalizationTest.txt ... test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 39 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [882439 refs] From nnorwitz at gmail.com Fri Nov 27 22:24:51 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 27 Nov 2009 16:24:51 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091127212451.GA28994@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881549 refs] From nnorwitz at gmail.com Fri Nov 27 23:52:19 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 27 Nov 2009 17:52:19 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20091127225219.GA28705@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_ssl leaked [-420, 420, -420] references, sum=-420 Less important issues: ---------------------- From nnorwitz at gmail.com Sat Nov 28 00:12:13 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 27 Nov 2009 18:12:13 -0500 Subject: [Python-checkins] Python Regression Test Failures all (1) Message-ID: <20091127231213.GA3516@kbk-i386-bb.psfb.org> 345 tests OK. 1 test failed: test_threading_local 27 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 Sleepycat Software: Berkeley DB 4.1.25: (December 19, 2002) Test path prefix: /tmp/z-test_bsddb3-28713 test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_socket test_socketserver test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 39 != 49 test_threadsignals test_time test_timeout test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle sh: line 1: python2.4: command not found sh: line 1: python2.6: command not found test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 345 tests OK. 1 test failed: test_threading_local 27 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools test_multiprocessing test_pep277 test_py3kwarn test_scriptpackages test_startfile test_sunaudiodev test_tcl test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [897991 refs] From solipsis at pitrou.net Sat Nov 28 00:47:27 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 28 Nov 2009 00:47:27 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76557): sum=12 Message-ID: <20091127234727.68CD81771C@ns6635.ovh.net> py3k results for svn r76557 (hg cset 68091fd10eb5) -------------------------------------------------- test_urllib leaked [6, 4, 2] references, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogFoH8Xz', '-x', 'test_httpservers'] From nnorwitz at gmail.com Sat Nov 28 10:25:07 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 28 Nov 2009 04:25:07 -0500 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20091128092507.GA567@kbk-i386-bb.psfb.org> 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly test_grammar test_opcodes test_dict test_builtin test_exceptions test_types test_unittest test_doctest test_doctest2 test_MimeWriter test_SimpleHTTPServer test_StringIO test___all__ test___future__ test__locale test_abc test_abstract_numbers test_aepack test_aepack skipped -- No module named aetypes test_aifc test_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ascii_formatd test_ast test_asynchat test_asyncore test_atexit test_audioop test_augassign test_base64 test_bastion test_bigaddrspace test_bigmem test_binascii test_binhex test_binop test_bisect test_bool test_bsddb test_bsddb185 test_bsddb185 skipped -- No module named bsddb185 test_bsddb3 test_bsddb3 skipped -- Use of the `bsddb' resource not enabled test_buffer test_bufio test_bytes test_bz2 test_calendar test_call test_capi test_cd test_cd skipped -- No module named cd test_cfgparser test_cgi test_charmapcodec test_cl test_cl skipped -- No module named cl test_class test_cmath test_cmd test_cmd_line test_cmd_line_script test_code test_codeccallbacks test_codecencodings_cn test_codecencodings_hk test_codecencodings_jp test_codecencodings_kr test_codecencodings_tw test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_codecs test_codeop test_coding test_coercion test_collections test_colorsys test_commands test_compare test_compile test_compileall test_compiler test_complex test_complex_args test_contains test_contextlib test_cookie test_cookielib test_copy test_copy_reg test_cpickle test_cprofile test_crypt test_csv test_ctypes test_curses test_curses skipped -- Use of the `curses' resource not enabled test_datetime test_dbm test_decimal test_decorators test_defaultdict test_deque test_descr test_descrtut test_difflib test_dircache test_dis test_distutils [19571 refs] [19571 refs] [19571 refs] [19568 refs] test_dl test_docxmlrpc test_dumbdbm test_dummy_thread test_dummy_threading test_email test_email_codecs test_email_renamed test_enumerate test_eof test_epoll test_epoll skipped -- kernel doesn't support epoll() test_errno test_exception_variations test_extcall test_fcntl test_file test_file2k test_filecmp test_fileinput test_fileio test_float test_fnmatch test_fork1 test_format test_fpformat test_fractions test_frozen test_ftplib test_funcattrs test_functools test_future test_future3 test_future4 test_future5 test_future_builtins test_gc test_gdbm test_generators test_genericpath test_genexps test_getargs test_getargs2 test_getopt test_gettext test_gl test_gl skipped -- No module named gl test_glob test_global test_grp test_gzip test_hash test_hashlib test_heapq test_hmac test_hotshot test_htmllib test_htmlparser test_httplib test_httpservers [15429 refs] [15429 refs] [15429 refs] [25443 refs] test_imageop test_imaplib test_imgfile test_imgfile skipped -- No module named imgfile test_imp test_import test_importhooks test_importlib test_index test_inspect test_int test_int_literal test_io test_ioctl test_ioctl skipped -- Unable to open /dev/tty test_isinstance test_iter test_iterlen test_itertools test_json test_kqueue test_kqueue skipped -- test works only on BSD test_largefile test_lib2to3 test_linecache test_linuxaudiodev test_linuxaudiodev skipped -- Use of the `audio' resource not enabled test_list test_locale test_logging test_long test_long_future test_longexp test_macos test_macos skipped -- No module named MacOS test_macostools test_macostools skipped -- No module named MacOS test_macpath test_mailbox test_marshal test_math test_md5 test_memoryio test_memoryview test_mhlib test_mimetools test_mimetypes test_minidom test_mmap test_module test_modulefinder test_multibytecodec test_multibytecodec_support test_multifile test_multiprocessing test_multiprocessing skipped -- This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770. test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_ossaudiodev test_ossaudiodev skipped -- Use of the `audio' resource not enabled test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_pdb test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [17017 refs] [17017 refs] test_plistlib test_poll test_popen [15434 refs] [15434 refs] [15434 refs] test_popen2 test_poplib test_posix test_posixpath test_pow test_pprint test_print test_profile test_profilehooks test_property test_pstats test_pty test_pwd test_py3kwarn test_py3kwarn skipped -- test.test_py3kwarn must be run with the -3 flag test_pyclbr test_pydoc [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20928 refs] [20927 refs] [20927 refs] test_pyexpat test_queue test_quopri [18223 refs] [18223 refs] test_random test_re test_readline test_repr test_resource test_rfc822 test_richcmp test_robotparser test_runpy test_sax test_scope test_scriptpackages test_scriptpackages skipped -- No module named aetools test_select test_set test_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [15429 refs] [15429 refs] [15432 refs] [15429 refs] test_slice test_smtplib test_smtpnet test_smtpnet skipped -- Use of the `network' resource not enabled test_socket test_socketserver test_socketserver skipped -- Use of the `network' resource not enabled test_softspace test_sort test_sqlite test_ssl test_startfile test_startfile skipped -- module os has no attribute startfile test_str test_strftime test_string test_stringprep test_strop test_strptime test_struct test_structmembers test_structseq test_subprocess [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [17290 refs] [15644 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] [15429 refs] . [15429 refs] [15429 refs] this bit of output is from a test of stdout in a different process ... [15429 refs] [15429 refs] [15644 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [15429 refs] [15429 refs] [15658 refs] [15452 refs] test_tarfile /tmp/python-test/local/lib/python2.7/test/test_tarfile.py:715: DeprecationWarning: use the filter argument instead tar.add(tempdir, arcname="empty_dir", exclude=exclude) /tmp/python-test/local/lib/python2.7/tarfile.py:2004: DeprecationWarning: use the filter argument instead recursive, exclude, filter) test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [15432 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [18742 refs] [20308 refs] [20122 refs] [20122 refs] [20122 refs] [20122 refs] test_threading_local test test_threading_local failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 20, in test_local_refs self._local_refs(50) File "/tmp/python-test/local/lib/python2.7/test/test_threading_local.py", line 37, in _local_refs self.assertEqual(len(deadlist), n-1) AssertionError: 48 != 49 test_threadsignals test_time test_timeout test_timeout skipped -- Use of the `network' resource not enabled test_tk test_tk skipped -- No module named _tkinter test_tokenize test_trace test_traceback test_transformer test_ttk_guionly test_ttk_guionly skipped -- No module named _tkinter test_ttk_textonly test_ttk_textonly skipped -- No module named _tkinter test_tuple test_typechecks test_ucn test_unary test_undocumented_details test_unicode test_unicode_file test_unicode_file skipped -- No Unicode filesystem semantics on this platform. test_unicodedata test_univnewlines test_univnewlines2k test_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllib2net skipped -- Use of the `network' resource not enabled test_urllibnet test_urllibnet skipped -- Use of the `network' resource not enabled test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref test_whichdb test_winreg test_winreg skipped -- No module named _winreg test_winsound test_winsound skipped -- No module named winsound test_with test_wsgiref test_xdrlib test_xml_etree test_xml_etree_c test_xmllib /tmp/python-test/local/lib/python2.7/test/test_xmllib.py:24: DeprecationWarning: The xmllib module is obsolete. Use xml.sax instead. import xmllib test_xmlrpc test_xpickle test_xpickle -- skipping backwards compat tests. Use 'regrtest.py -u xpickle' to run them. test_xrange test_zipfile test_zipfile64 test_zipfile64 skipped -- test requires loads of disk-space bytes and a long time to run test_zipimport test_zipimport_support test_zlib 339 tests OK. 1 test failed: test_threading_local 36 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_multiprocessing test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_smtpnet test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_tk test_ttk_guionly test_ttk_textonly test_unicode_file test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [881549 refs] From python-checkins at python.org Sat Nov 28 11:44:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 10:44:20 -0000 Subject: [Python-checkins] r76558 - in python/trunk: Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h configure configure.in pyconfig.h.in setup.py Message-ID: Author: mark.dickinson Date: Sat Nov 28 11:44:20 2009 New Revision: 76558 Log: Issue #7272, continued: don't re-use existing HAVE_BROKEN_POSIX_SEMAPHORES to indicate that semaphores aren't available; define a new variable POSIX_SEMAPHORES_NOT_ENABLED instead. Modified: python/trunk/Modules/_multiprocessing/multiprocessing.c python/trunk/Modules/_multiprocessing/multiprocessing.h python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in python/trunk/setup.py Modified: python/trunk/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.c (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.c Sat Nov 28 11:44:20 2009 @@ -251,7 +251,7 @@ PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); #if defined(MS_WINDOWS) || \ - (defined(HAVE_SEM_OPEN) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)) + (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return; @@ -298,7 +298,7 @@ Py_DECREF(temp); Py_DECREF(value); return; } \ Py_DECREF(value) -#if defined(HAVE_SEM_OPEN) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) +#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) ADD_FLAG(HAVE_SEM_OPEN); #endif #ifdef HAVE_SEM_TIMEDWAIT Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.h (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.h Sat Nov 28 11:44:20 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# if defined(HAVE_SEM_OPEN) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) +# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) # include typedef sem_t *SEM_HANDLE; # endif Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sat Nov 28 11:44:20 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76432 . +# From configure.in Revision: 76550 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -23876,7 +23876,7 @@ then cat >>confdefs.h <<\_ACEOF -#define HAVE_BROKEN_POSIX_SEMAPHORES 1 +#define POSIX_SEMAPHORES_NOT_ENABLED 1 _ACEOF fi Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sat Nov 28 11:44:20 2009 @@ -3419,8 +3419,8 @@ AC_MSG_RESULT($ac_cv_posix_semaphores_enabled) if test $ac_cv_posix_semaphores_enabled = no then - AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, - [Define if the Posix semaphores do not work on your system]) + AC_DEFINE(POSIX_SEMAPHORES_NOT_ENABLED, 1, + [Define if POSIX semaphores aren't enabled on your system]) fi Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Sat Nov 28 11:44:20 2009 @@ -909,6 +909,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Define if POSIX semaphores aren't enabled on your system */ +#undef POSIX_SEMAPHORES_NOT_ENABLED + /* Defined if PTHREAD_SCOPE_SYSTEM supported. */ #undef PTHREAD_SYSTEM_SCHED_SUPPORTED Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Sat Nov 28 11:44:20 2009 @@ -1316,7 +1316,7 @@ '_multiprocessing/socket_connection.c' ] if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not - sysconfig.get_config_var('HAVE_BROKEN_POSIX_SEMAPHORES')): + sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From python-checkins at python.org Sat Nov 28 12:11:50 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 28 Nov 2009 11:11:50 -0000 Subject: [Python-checkins] r76559 - python/trunk/Doc/library/os.rst Message-ID: Author: georg.brandl Date: Sat Nov 28 12:11:50 2009 New Revision: 76559 Log: Fix versions and spacing. Modified: python/trunk/Doc/library/os.rst Modified: python/trunk/Doc/library/os.rst ============================================================================== --- python/trunk/Doc/library/os.rst (original) +++ python/trunk/Doc/library/os.rst Sat Nov 28 12:11:50 2009 @@ -173,19 +173,22 @@ Return the parent's process id. Availability: Unix. + .. function:: getresuid() Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. Availability: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 2.7 + .. function:: getresgid() Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved user ids. Availability: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 2.7 + .. function:: getuid() @@ -264,19 +267,22 @@ Set the current process's real and effective group ids. Availability: Unix. + .. function:: setresgid(rgid, egid, sgid) Set the current process's real, effective, and saved group ids. Availability: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 2.7 + .. function:: setresuid(ruid, euid, suid) Set the current process's real, effective, and saved user ids. Availibility: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 2.7 + .. function:: setreuid(ruid, euid) From python-checkins at python.org Sat Nov 28 12:12:26 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 28 Nov 2009 11:12:26 -0000 Subject: [Python-checkins] r76560 - in python/branches/py3k: Doc/library/os.rst Message-ID: Author: georg.brandl Date: Sat Nov 28 12:12:26 2009 New Revision: 76560 Log: Merged revisions 76559 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76559 | georg.brandl | 2009-11-28 12:11:50 +0100 (Sa, 28 Nov 2009) | 1 line Fix versions and spacing. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/os.rst Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sat Nov 28 12:12:26 2009 @@ -196,19 +196,22 @@ Return the parent's process id. Availability: Unix. + .. function:: getresuid() Return a tuple (ruid, euid, suid) denoting the current process's real, effective, and saved user ids. Availability: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 3.2 + .. function:: getresgid() Return a tuple (rgid, egid, sgid) denoting the current process's real, effective, and saved user ids. Availability: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 3.2 + .. function:: getuid() @@ -284,19 +287,22 @@ Set the current process's real and effective group ids. Availability: Unix. + .. function:: setresgid(rgid, egid, sgid) Set the current process's real, effective, and saved group ids. Availability: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 3.2 + .. function:: setresuid(ruid, euid, suid) Set the current process's real, effective, and saved user ids. Availibility: Unix. - .. versionadded:: 2.7/3.2 + .. versionadded:: 3.2 + .. function:: setreuid(ruid, euid) From python-checkins at python.org Sat Nov 28 13:30:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:30:36 -0000 Subject: [Python-checkins] r76561 - in python/trunk: Include/pyport.h Objects/complexobject.c Objects/floatobject.c Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:30:36 2009 New Revision: 76561 Log: Include ieeefp.h (when available) in pyport.h instead of individually in Objects/floatobject.c and Objects/complexobject.c. This should silence compiler warnings about implicit declaration of the 'finite' function on Solaris. Modified: python/trunk/Include/pyport.h python/trunk/Objects/complexobject.c python/trunk/Objects/floatobject.c Modified: python/trunk/Include/pyport.h ============================================================================== --- python/trunk/Include/pyport.h (original) +++ python/trunk/Include/pyport.h Sat Nov 28 13:30:36 2009 @@ -305,6 +305,10 @@ #include +#ifdef HAVE_IEEEFP_H +#include /* needed for 'finite' declaration on some platforms */ +#endif + #include /* Moved here from the math section, before extern "C" */ /******************************************** Modified: python/trunk/Objects/complexobject.c ============================================================================== --- python/trunk/Objects/complexobject.c (original) +++ python/trunk/Objects/complexobject.c Sat Nov 28 13:30:36 2009 @@ -8,10 +8,6 @@ #include "Python.h" #include "structmember.h" -#ifdef HAVE_IEEEFP_H -#include -#endif - #ifndef WITHOUT_COMPLEX /* Precisions used by repr() and str(), respectively. Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Sat Nov 28 13:30:36 2009 @@ -15,10 +15,6 @@ #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) -#ifdef HAVE_IEEEFP_H -#include -#endif - #ifdef _OSF_SOURCE /* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ extern int finite(double); From python-checkins at python.org Sat Nov 28 13:33:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:33:36 -0000 Subject: [Python-checkins] r76562 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:33:35 2009 New Revision: 76562 Log: Blocked revisions 76561 via svnmerge ........ r76561 | mark.dickinson | 2009-11-28 12:30:36 +0000 (Sat, 28 Nov 2009) | 5 lines Include ieeefp.h (when available) in pyport.h instead of individually in Objects/floatobject.c and Objects/complexobject.c. This should silence compiler warnings about implicit declaration of the 'finite' function on Solaris. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Nov 28 13:35:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:35:43 -0000 Subject: [Python-checkins] r76563 - in python/branches/py3k: Include/pyport.h Objects/complexobject.c Objects/floatobject.c Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:35:42 2009 New Revision: 76563 Log: Merged revisions 76561 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76561 | mark.dickinson | 2009-11-28 12:30:36 +0000 (Sat, 28 Nov 2009) | 5 lines Include ieeefp.h (when available) in pyport.h instead of individually in Objects/floatobject.c and Objects/complexobject.c. This should silence compiler warnings about implicit declaration of the 'finite' function on Solaris. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/pyport.h python/branches/py3k/Objects/complexobject.c python/branches/py3k/Objects/floatobject.c Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Sat Nov 28 13:35:42 2009 @@ -295,6 +295,10 @@ #include +#ifdef HAVE_IEEEFP_H +#include /* needed for 'finite' declaration on some platforms */ +#endif + #include /* Moved here from the math section, before extern "C" */ /******************************************** Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Sat Nov 28 13:35:42 2009 @@ -8,10 +8,6 @@ #include "Python.h" #include "structmember.h" -#ifdef HAVE_IEEEFP_H -#include -#endif - /* elementary operations on complex numbers */ static Py_complex c_1 = {1., 0.}; Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Sat Nov 28 13:35:42 2009 @@ -15,10 +15,6 @@ #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) -#ifdef HAVE_IEEEFP_H -#include -#endif - #ifdef _OSF_SOURCE /* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ From python-checkins at python.org Sat Nov 28 13:37:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:37:41 -0000 Subject: [Python-checkins] r76564 - python/branches/release31-maint Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:37:41 2009 New Revision: 76564 Log: Blocked revisions 76563 via svnmerge ................ r76563 | mark.dickinson | 2009-11-28 12:35:42 +0000 (Sat, 28 Nov 2009) | 12 lines Merged revisions 76561 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76561 | mark.dickinson | 2009-11-28 12:30:36 +0000 (Sat, 28 Nov 2009) | 5 lines Include ieeefp.h (when available) in pyport.h instead of individually in Objects/floatobject.c and Objects/complexobject.c. This should silence compiler warnings about implicit declaration of the 'finite' function on Solaris. ........ ................ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sat Nov 28 13:39:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:39:55 -0000 Subject: [Python-checkins] r76565 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:39:54 2009 New Revision: 76565 Log: Blocked revisions 76432,76558 via svnmerge ........ r76432 | mark.dickinson | 2009-11-20 19:30:22 +0000 (Fri, 20 Nov 2009) | 5 lines Issue #7272: Add configure test to detect whether sem_open works properly, and use this to skip test_multiprocessing on platforms where sem_open raises a signal. This should fix some FreeBSD buildbot failures for test_multiprocessing. ........ r76558 | mark.dickinson | 2009-11-28 10:44:20 +0000 (Sat, 28 Nov 2009) | 4 lines Issue #7272, continued: don't re-use existing HAVE_BROKEN_POSIX_SEMAPHORES to indicate that semaphores aren't available; define a new variable POSIX_SEMAPHORES_NOT_ENABLED instead. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Nov 28 13:48:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:48:44 -0000 Subject: [Python-checkins] r76566 - in python/branches/py3k: Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h configure configure.in pyconfig.h.in setup.py Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:48:43 2009 New Revision: 76566 Log: Merged revisions 76432,76558 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76432 | mark.dickinson | 2009-11-20 19:30:22 +0000 (Fri, 20 Nov 2009) | 5 lines Issue #7272: Add configure test to detect whether sem_open works properly, and use this to skip test_multiprocessing on platforms where sem_open raises a signal. This should fix some FreeBSD buildbot failures for test_multiprocessing. ........ r76558 | mark.dickinson | 2009-11-28 10:44:20 +0000 (Sat, 28 Nov 2009) | 4 lines Issue #7272, continued: don't re-use existing HAVE_BROKEN_POSIX_SEMAPHORES to indicate that semaphores aren't available; define a new variable POSIX_SEMAPHORES_NOT_ENABLED instead. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_multiprocessing/multiprocessing.c python/branches/py3k/Modules/_multiprocessing/multiprocessing.h python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in python/branches/py3k/setup.py Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/multiprocessing.c (original) +++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.c Sat Nov 28 13:48:43 2009 @@ -263,7 +263,8 @@ Py_INCREF(&ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); -#if defined(MS_WINDOWS) || defined(HAVE_SEM_OPEN) +#if defined(MS_WINDOWS) || \ + (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return NULL; @@ -311,7 +312,7 @@ Py_DECREF(temp); Py_DECREF(value); return NULL; } \ Py_DECREF(value) -#ifdef HAVE_SEM_OPEN +#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) ADD_FLAG(HAVE_SEM_OPEN); #endif #ifdef HAVE_SEM_TIMEDWAIT Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.h Sat Nov 28 13:48:43 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# ifdef HAVE_SEM_OPEN +# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) # include typedef sem_t *SEM_HANDLE; # endif Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sat Nov 28 13:48:43 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76405 . +# From configure.in Revision: 76552 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.2. # @@ -23587,6 +23587,90 @@ LIBS=$LIBS_SAVE +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +{ echo "$as_me:$LINENO: checking whether POSIX semaphores are enabled" >&5 +echo $ECHO_N "checking whether POSIX semaphores are enabled... $ECHO_C" >&6; } +if test "${ac_cv_posix_semaphores_enabled+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_posix_semaphores_enabled=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_posix_semaphores_enabled=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_posix_semaphores_enabled=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_posix_semaphores_enabled" >&5 +echo "${ECHO_T}$ac_cv_posix_semaphores_enabled" >&6; } +if test $ac_cv_posix_semaphores_enabled = no +then + +cat >>confdefs.h <<\_ACEOF +#define POSIX_SEMAPHORES_NOT_ENABLED 1 +_ACEOF + +fi + # Multiprocessing check for broken sem_getvalue { echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sat Nov 28 13:48:43 2009 @@ -3290,6 +3290,40 @@ LIBS=$LIBS_SAVE +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +AC_MSG_CHECKING(whether POSIX semaphores are enabled) +AC_CACHE_VAL(ac_cv_posix_semaphores_enabled, +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} +], ac_cv_posix_semaphores_enabled=yes, + ac_cv_posix_semaphores_enabled=no, + ac_cv_posix_semaphores_enabled=yes) +) +AC_MSG_RESULT($ac_cv_posix_semaphores_enabled) +if test $ac_cv_posix_semaphores_enabled = no +then + AC_DEFINE(POSIX_SEMAPHORES_NOT_ENABLED, 1, + [Define if POSIX semaphores aren't enabled on your system]) +fi + # Multiprocessing check for broken sem_getvalue AC_MSG_CHECKING(for broken sem_getvalue) AC_CACHE_VAL(ac_cv_broken_sem_getvalue, Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sat Nov 28 13:48:43 2009 @@ -916,6 +916,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Define if POSIX semaphores aren't enabled on your system */ +#undef POSIX_SEMAPHORES_NOT_ENABLED + /* Defined if PTHREAD_SCOPE_SYSTEM supported. */ #undef PTHREAD_SYSTEM_SCHED_SUPPORTED Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Sat Nov 28 13:48:43 2009 @@ -1183,7 +1183,8 @@ multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c', '_multiprocessing/socket_connection.c' ] - if sysconfig.get_config_var('HAVE_SEM_OPEN'): + if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not + sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From python-checkins at python.org Sat Nov 28 13:52:39 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 12:52:39 -0000 Subject: [Python-checkins] r76567 - in python/branches/release31-maint: Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h configure configure.in pyconfig.h.in setup.py Message-ID: Author: mark.dickinson Date: Sat Nov 28 13:52:39 2009 New Revision: 76567 Log: Merged revisions 76566 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76566 | mark.dickinson | 2009-11-28 12:48:43 +0000 (Sat, 28 Nov 2009) | 18 lines Merged revisions 76432,76558 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76432 | mark.dickinson | 2009-11-20 19:30:22 +0000 (Fri, 20 Nov 2009) | 5 lines Issue #7272: Add configure test to detect whether sem_open works properly, and use this to skip test_multiprocessing on platforms where sem_open raises a signal. This should fix some FreeBSD buildbot failures for test_multiprocessing. ........ r76558 | mark.dickinson | 2009-11-28 10:44:20 +0000 (Sat, 28 Nov 2009) | 4 lines Issue #7272, continued: don't re-use existing HAVE_BROKEN_POSIX_SEMAPHORES to indicate that semaphores aren't available; define a new variable POSIX_SEMAPHORES_NOT_ENABLED instead. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.c python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.h python/branches/release31-maint/configure python/branches/release31-maint/configure.in python/branches/release31-maint/pyconfig.h.in python/branches/release31-maint/setup.py Modified: python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.c (original) +++ python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.c Sat Nov 28 13:52:39 2009 @@ -263,7 +263,8 @@ Py_INCREF(&ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); -#if defined(MS_WINDOWS) || defined(HAVE_SEM_OPEN) +#if defined(MS_WINDOWS) || \ + (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return NULL; @@ -311,7 +312,7 @@ Py_DECREF(temp); Py_DECREF(value); return NULL; } \ Py_DECREF(value) -#ifdef HAVE_SEM_OPEN +#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) ADD_FLAG(HAVE_SEM_OPEN); #endif #ifdef HAVE_SEM_TIMEDWAIT Modified: python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/release31-maint/Modules/_multiprocessing/multiprocessing.h Sat Nov 28 13:52:39 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# ifdef HAVE_SEM_OPEN +# if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED) # include typedef sem_t *SEM_HANDLE; # endif Modified: python/branches/release31-maint/configure ============================================================================== --- python/branches/release31-maint/configure (original) +++ python/branches/release31-maint/configure Sat Nov 28 13:52:39 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 75727 . +# From configure.in Revision: 76406 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -3802,7 +3802,7 @@ { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi -rm -f -r conftest* +rm -f conftest* @@ -5350,7 +5350,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -5371,7 +5371,7 @@ else ac_cv_header_stdc=no fi -rm -f -r conftest* +rm -f conftest* fi @@ -6469,7 +6469,7 @@ fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $was_it_defined" >&5 echo "${ECHO_T}$was_it_defined" >&6; } @@ -6999,7 +6999,7 @@ else ac_cv_type_uid_t=no fi -rm -f -r conftest* +rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 @@ -14409,7 +14409,7 @@ else unistd_defines_pthreads=no fi -rm -f -r conftest* +rm -f conftest* { echo "$as_me:$LINENO: result: $unistd_defines_pthreads" >&5 echo "${ECHO_T}$unistd_defines_pthreads" >&6; } @@ -15877,7 +15877,7 @@ $EGREP "yes" >/dev/null 2>&1; then ipv6type=$i fi -rm -f -r conftest* +rm -f conftest* ;; kame) @@ -15900,7 +15900,7 @@ ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-glibc) @@ -15921,7 +15921,7 @@ ipv6type=$i; ipv6trylibc=yes fi -rm -f -r conftest* +rm -f conftest* ;; linux-inet6) @@ -15959,7 +15959,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; v6d) @@ -15982,7 +15982,7 @@ ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f -r conftest* +rm -f conftest* ;; zeta) @@ -16004,7 +16004,7 @@ ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f -r conftest* +rm -f conftest* ;; esac @@ -22531,6 +22531,90 @@ LIBS=$LIBS_SAVE +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +{ echo "$as_me:$LINENO: checking whether POSIX semaphores are enabled" >&5 +echo $ECHO_N "checking whether POSIX semaphores are enabled... $ECHO_C" >&6; } +if test "${ac_cv_posix_semaphores_enabled+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_posix_semaphores_enabled=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_posix_semaphores_enabled=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_posix_semaphores_enabled=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_posix_semaphores_enabled" >&5 +echo "${ECHO_T}$ac_cv_posix_semaphores_enabled" >&6; } +if test $ac_cv_posix_semaphores_enabled = no +then + +cat >>confdefs.h <<\_ACEOF +#define POSIX_SEMAPHORES_NOT_ENABLED 1 +_ACEOF + +fi + # Multiprocessing check for broken sem_getvalue { echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } @@ -23989,7 +24073,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -24008,7 +24092,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi @@ -24278,7 +24362,7 @@ _ACEOF fi -rm -f -r conftest* +rm -f conftest* fi Modified: python/branches/release31-maint/configure.in ============================================================================== --- python/branches/release31-maint/configure.in (original) +++ python/branches/release31-maint/configure.in Sat Nov 28 13:52:39 2009 @@ -3338,6 +3338,40 @@ LIBS=$LIBS_SAVE +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +AC_MSG_CHECKING(whether POSIX semaphores are enabled) +AC_CACHE_VAL(ac_cv_posix_semaphores_enabled, +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} +], ac_cv_posix_semaphores_enabled=yes, + ac_cv_posix_semaphores_enabled=no, + ac_cv_posix_semaphores_enabled=yes) +) +AC_MSG_RESULT($ac_cv_posix_semaphores_enabled) +if test $ac_cv_posix_semaphores_enabled = no +then + AC_DEFINE(POSIX_SEMAPHORES_NOT_ENABLED, 1, + [Define if POSIX semaphores aren't enabled on your system]) +fi + # Multiprocessing check for broken sem_getvalue AC_MSG_CHECKING(for broken sem_getvalue) AC_TRY_RUN([ Modified: python/branches/release31-maint/pyconfig.h.in ============================================================================== --- python/branches/release31-maint/pyconfig.h.in (original) +++ python/branches/release31-maint/pyconfig.h.in Sat Nov 28 13:52:39 2009 @@ -895,6 +895,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Define if POSIX semaphores aren't enabled on your system */ +#undef POSIX_SEMAPHORES_NOT_ENABLED + /* Defined if PTHREAD_SCOPE_SYSTEM supported. */ #undef PTHREAD_SYSTEM_SCHED_SUPPORTED Modified: python/branches/release31-maint/setup.py ============================================================================== --- python/branches/release31-maint/setup.py (original) +++ python/branches/release31-maint/setup.py Sat Nov 28 13:52:39 2009 @@ -1191,7 +1191,8 @@ multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c', '_multiprocessing/socket_connection.c' ] - if sysconfig.get_config_var('HAVE_SEM_OPEN'): + if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not + sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From python-checkins at python.org Sat Nov 28 14:13:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 13:13:13 -0000 Subject: [Python-checkins] r76568 - in python/trunk: configure configure.in Message-ID: Author: mark.dickinson Date: Sat Nov 28 14:13:13 2009 New Revision: 76568 Log: Multiprocessing configure checks don't need LIBM Modified: python/trunk/configure python/trunk/configure.in Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sat Nov 28 14:13:13 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 76550 . +# From configure.in Revision: 76558 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -23797,175 +23797,6 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" -# For multiprocessing module, check that sem_open -# actually works. For FreeBSD versions <= 7.2, -# the kernel module that provides POSIX semaphores -# isn't loaded by default, so an attempt to call -# sem_open results in a 'Signal 12' error. -{ echo "$as_me:$LINENO: checking whether POSIX semaphores are enabled" >&5 -echo $ECHO_N "checking whether POSIX semaphores are enabled... $ECHO_C" >&6; } -if test "${ac_cv_posix_semaphores_enabled+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_posix_semaphores_enabled=yes -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include -#include -#include -#include - -int main(void) { - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - if (a == SEM_FAILED) { - perror("sem_open"); - return 1; - } - sem_close(a); - return 0; -} - -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_posix_semaphores_enabled=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_posix_semaphores_enabled=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - -fi - -{ echo "$as_me:$LINENO: result: $ac_cv_posix_semaphores_enabled" >&5 -echo "${ECHO_T}$ac_cv_posix_semaphores_enabled" >&6; } -if test $ac_cv_posix_semaphores_enabled = no -then - -cat >>confdefs.h <<\_ACEOF -#define POSIX_SEMAPHORES_NOT_ENABLED 1 -_ACEOF - -fi - - -# Multiprocessing check for broken sem_getvalue -{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 -echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } -if test "${ac_cv_broken_sem_getvalue+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_broken_sem_getvalue=yes -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include -#include -#include -#include - -int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - int count; - int res; - if(a==SEM_FAILED){ - perror("sem_open"); - return 1; - - } - res = sem_getvalue(a, &count); - sem_close(a); - return res==-1 ? 1 : 0; -} - -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_broken_sem_getvalue=no -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_broken_sem_getvalue=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - -fi - -{ echo "$as_me:$LINENO: result: $ac_cv_broken_sem_getvalue" >&5 -echo "${ECHO_T}$ac_cv_broken_sem_getvalue" >&6; } -if test $ac_cv_broken_sem_getvalue = yes -then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_BROKEN_SEM_GETVALUE 1 -_ACEOF - -fi - # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. { echo "$as_me:$LINENO: checking whether tanh preserves the sign of zero" >&5 @@ -24448,6 +24279,174 @@ LIBS=$LIBS_SAVE +# For multiprocessing module, check that sem_open +# actually works. For FreeBSD versions <= 7.2, +# the kernel module that provides POSIX semaphores +# isn't loaded by default, so an attempt to call +# sem_open results in a 'Signal 12' error. +{ echo "$as_me:$LINENO: checking whether POSIX semaphores are enabled" >&5 +echo $ECHO_N "checking whether POSIX semaphores are enabled... $ECHO_C" >&6; } +if test "${ac_cv_posix_semaphores_enabled+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_posix_semaphores_enabled=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + return 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_posix_semaphores_enabled=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_posix_semaphores_enabled=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_posix_semaphores_enabled" >&5 +echo "${ECHO_T}$ac_cv_posix_semaphores_enabled" >&6; } +if test $ac_cv_posix_semaphores_enabled = no +then + +cat >>confdefs.h <<\_ACEOF +#define POSIX_SEMAPHORES_NOT_ENABLED 1 +_ACEOF + +fi + +# Multiprocessing check for broken sem_getvalue +{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 +echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } +if test "${ac_cv_broken_sem_getvalue+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_broken_sem_getvalue=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_broken_sem_getvalue=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_broken_sem_getvalue=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_broken_sem_getvalue" >&5 +echo "${ECHO_T}$ac_cv_broken_sem_getvalue" >&6; } +if test $ac_cv_broken_sem_getvalue = yes +then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_SEM_GETVALUE 1 +_ACEOF + +fi + # determine what size digit to use for Python's longs { echo "$as_me:$LINENO: checking digit size for Python's longs" >&5 echo $ECHO_N "checking digit size for Python's longs... $ECHO_C" >&6; } Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sat Nov 28 14:13:13 2009 @@ -3389,6 +3389,38 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" +# On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of +# -0. on some architectures. +AC_MSG_CHECKING(whether tanh preserves the sign of zero) +AC_CACHE_VAL(ac_cv_tanh_preserves_zero_sign, [ +AC_TRY_RUN([ +#include +#include +int main() { + /* return 0 if either negative zeros don't exist + on this platform or if negative zeros exist + and tanh(-0.) == -0. */ + if (atan2(0., -1.) == atan2(-0., -1.) || + atan2(tanh(-0.), -1.) == atan2(-0., -1.)) exit(0); + else exit(1); +} +], +ac_cv_tanh_preserves_zero_sign=yes, +ac_cv_tanh_preserves_zero_sign=no, +ac_cv_tanh_preserves_zero_sign=no)]) +AC_MSG_RESULT($ac_cv_tanh_preserves_zero_sign) +if test "$ac_cv_tanh_preserves_zero_sign" = yes +then + AC_DEFINE(TANH_PRESERVES_ZERO_SIGN, 1, + [Define if tanh(-0.) is -0., or if platform doesn't have signed zeros]) +fi + +AC_CHECK_FUNCS([acosh asinh atanh copysign erf erfc expm1 finite gamma]) +AC_CHECK_FUNCS([hypot lgamma log1p round tgamma]) +AC_CHECK_DECLS([isinf, isnan, isfinite], [], [], [[#include ]]) + +LIBS=$LIBS_SAVE + # For multiprocessing module, check that sem_open # actually works. For FreeBSD versions <= 7.2, # the kernel module that provides POSIX semaphores @@ -3423,7 +3455,6 @@ [Define if POSIX semaphores aren't enabled on your system]) fi - # Multiprocessing check for broken sem_getvalue AC_MSG_CHECKING(for broken sem_getvalue) AC_CACHE_VAL(ac_cv_broken_sem_getvalue, @@ -3458,38 +3489,6 @@ [define to 1 if your sem_getvalue is broken.]) fi -# On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of -# -0. on some architectures. -AC_MSG_CHECKING(whether tanh preserves the sign of zero) -AC_CACHE_VAL(ac_cv_tanh_preserves_zero_sign, [ -AC_TRY_RUN([ -#include -#include -int main() { - /* return 0 if either negative zeros don't exist - on this platform or if negative zeros exist - and tanh(-0.) == -0. */ - if (atan2(0., -1.) == atan2(-0., -1.) || - atan2(tanh(-0.), -1.) == atan2(-0., -1.)) exit(0); - else exit(1); -} -], -ac_cv_tanh_preserves_zero_sign=yes, -ac_cv_tanh_preserves_zero_sign=no, -ac_cv_tanh_preserves_zero_sign=no)]) -AC_MSG_RESULT($ac_cv_tanh_preserves_zero_sign) -if test "$ac_cv_tanh_preserves_zero_sign" = yes -then - AC_DEFINE(TANH_PRESERVES_ZERO_SIGN, 1, - [Define if tanh(-0.) is -0., or if platform doesn't have signed zeros]) -fi - -AC_CHECK_FUNCS([acosh asinh atanh copysign erf erfc expm1 finite gamma]) -AC_CHECK_FUNCS([hypot lgamma log1p round tgamma]) -AC_CHECK_DECLS([isinf, isnan, isfinite], [], [], [[#include ]]) - -LIBS=$LIBS_SAVE - # determine what size digit to use for Python's longs AC_MSG_CHECKING([digit size for Python's longs]) AC_ARG_ENABLE(big-digits, From python-checkins at python.org Sat Nov 28 14:13:39 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 13:13:39 -0000 Subject: [Python-checkins] r76569 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Sat Nov 28 14:13:39 2009 New Revision: 76569 Log: Blocked revisions 76568 via svnmerge ........ r76568 | mark.dickinson | 2009-11-28 13:13:13 +0000 (Sat, 28 Nov 2009) | 1 line Multiprocessing configure checks don't need LIBM ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Nov 28 14:14:03 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 13:14:03 -0000 Subject: [Python-checkins] r76570 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Sat Nov 28 14:14:02 2009 New Revision: 76570 Log: Blocked revisions 76568 via svnmerge ........ r76568 | mark.dickinson | 2009-11-28 13:13:13 +0000 (Sat, 28 Nov 2009) | 1 line Multiprocessing configure checks don't need LIBM ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Nov 28 16:55:58 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 28 Nov 2009 15:55:58 -0000 Subject: [Python-checkins] r76571 - in python/trunk: Lib/copy.py Lib/test/test_copy.py Misc/ACKS Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sat Nov 28 16:55:58 2009 New Revision: 76571 Log: Issue #1515: Enable use of deepcopy() with instance methods. Patch by Robert Collins. Modified: python/trunk/Lib/copy.py python/trunk/Lib/test/test_copy.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS Modified: python/trunk/Lib/copy.py ============================================================================== --- python/trunk/Lib/copy.py (original) +++ python/trunk/Lib/copy.py Sat Nov 28 16:55:58 2009 @@ -260,6 +260,10 @@ if PyStringMap is not None: d[PyStringMap] = _deepcopy_dict +def _deepcopy_method(x, memo): # Copy instance methods + return type(x)(x.im_func, deepcopy(x.im_self, memo), x.im_class) +_deepcopy_dispatch[types.MethodType] = _deepcopy_method + def _keep_alive(x, memo): """Keeps a reference to the object x in the memo. Modified: python/trunk/Lib/test/test_copy.py ============================================================================== --- python/trunk/Lib/test/test_copy.py (original) +++ python/trunk/Lib/test/test_copy.py Sat Nov 28 16:55:58 2009 @@ -672,6 +672,17 @@ del d self.assertEqual(len(v), 1) + def test_deepcopy_bound_method(self): + class Foo(object): + def m(self): + pass + f = Foo() + f.b = f.m + g = copy.deepcopy(f) + self.assertEqual(g.m, g.b) + self.assertTrue(g.b.im_self is g) + g.b() + def global_foo(x, y): return x+y Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Sat Nov 28 16:55:58 2009 @@ -145,6 +145,7 @@ Dave Cole Benjamin Collar Jeffery Collins +Robert Collins Paul Colomiets Matt Conway David M. Cooke Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Nov 28 16:55:58 2009 @@ -483,6 +483,9 @@ Library ------- +- Issue #1515: Enable use of deepcopy() with instance methods. Patch by + Robert Collins. + - Issue #7403: logging: Fixed possible race condition in lock creation. - Issue #6845: Add restart support for binary upload in ftplib. The From python-checkins at python.org Sat Nov 28 16:58:28 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 28 Nov 2009 15:58:28 -0000 Subject: [Python-checkins] r76572 - in python/branches/py3k: Lib/copy.py Lib/test/test_copy.py Misc/ACKS Misc/NEWS Message-ID: Author: antoine.pitrou Date: Sat Nov 28 16:58:27 2009 New Revision: 76572 Log: Merged revisions 76571 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76571 | antoine.pitrou | 2009-11-28 16:55:58 +0100 (sam., 28 nov. 2009) | 3 lines Issue #1515: Enable use of deepcopy() with instance methods. Patch by Robert Collins. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/copy.py python/branches/py3k/Lib/test/test_copy.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/copy.py ============================================================================== --- python/branches/py3k/Lib/copy.py (original) +++ python/branches/py3k/Lib/copy.py Sat Nov 28 16:58:27 2009 @@ -238,6 +238,10 @@ if PyStringMap is not None: d[PyStringMap] = _deepcopy_dict +def _deepcopy_method(x, memo): # Copy instance methods + return type(x)(x.__func__, deepcopy(x.__self__, memo)) +_deepcopy_dispatch[types.MethodType] = _deepcopy_method + def _keep_alive(x, memo): """Keeps a reference to the object x in the memo. Modified: python/branches/py3k/Lib/test/test_copy.py ============================================================================== --- python/branches/py3k/Lib/test/test_copy.py (original) +++ python/branches/py3k/Lib/test/test_copy.py Sat Nov 28 16:58:27 2009 @@ -677,6 +677,17 @@ del d self.assertEqual(len(v), 1) + def test_deepcopy_bound_method(self): + class Foo(object): + def m(self): + pass + f = Foo() + f.b = f.m + g = copy.deepcopy(f) + self.assertEqual(g.m, g.b) + self.assertTrue(g.b.__self__ is g) + g.b() + def global_foo(x, y): return x+y Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sat Nov 28 16:58:27 2009 @@ -144,6 +144,7 @@ Dave Cole Benjamin Collar Jeffery Collins +Robert Collins Paul Colomiets Matt Conway David M. Cooke Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Nov 28 16:58:27 2009 @@ -140,6 +140,9 @@ Library ------- +- Issue #1515: Enable use of deepcopy() with instance methods. Patch by + Robert Collins. + - Issue #7403: logging: Fixed possible race condition in lock creation. - Issue #6845: Add restart support for binary upload in ftplib. The From python-checkins at python.org Sat Nov 28 17:12:28 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 28 Nov 2009 16:12:28 -0000 Subject: [Python-checkins] r76573 - in python/branches/py3k: Lib/test/test_traceback.py Lib/traceback.py Misc/NEWS Python/pythonrun.c Message-ID: Author: antoine.pitrou Date: Sat Nov 28 17:12:28 2009 New Revision: 76573 Log: Issue #4486: When an exception has an explicit cause, do not print its implicit context too. Modified: python/branches/py3k/Lib/test/test_traceback.py python/branches/py3k/Lib/traceback.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Lib/test/test_traceback.py ============================================================================== --- python/branches/py3k/Lib/test/test_traceback.py (original) +++ python/branches/py3k/Lib/test/test_traceback.py Sat Nov 28 17:12:28 2009 @@ -253,6 +253,26 @@ self.check_zero_div(blocks[0]) self.assertTrue('inner_raise() # Marker' in blocks[2]) + def test_cause_and_context(self): + # When both a cause and a context are set, only the cause should be + # displayed and the context should be muted. + def inner_raise(): + try: + self.zero_div() + except ZeroDivisionError as _e: + e = _e + try: + xyzzy + except NameError: + raise KeyError from e + def outer_raise(): + inner_raise() # Marker + blocks = boundaries.split(self.get_report(outer_raise)) + self.assertEquals(len(blocks), 3) + self.assertEquals(blocks[1], cause_message) + self.check_zero_div(blocks[0]) + self.assert_('inner_raise() # Marker' in blocks[2]) + def test_cause_recursive(self): def inner_raise(): try: Modified: python/branches/py3k/Lib/traceback.py ============================================================================== --- python/branches/py3k/Lib/traceback.py (original) +++ python/branches/py3k/Lib/traceback.py Sat Nov 28 17:12:28 2009 @@ -120,13 +120,14 @@ seen.add(exc) its = [] cause = exc.__cause__ - context = exc.__context__ if cause is not None and cause not in seen: its.append(_iter_chain(cause, None, seen)) its.append([(_cause_message, None)]) - if context is not None and context is not cause and context not in seen: - its.append(_iter_chain(context, None, seen)) - its.append([(_context_message, None)]) + else: + context = exc.__context__ + if context is not None and context not in seen: + its.append(_iter_chain(context, None, seen)) + its.append([(_context_message, None)]) its.append([(exc, custom_tb or exc.__traceback__)]) # itertools.chain is in an extension module and may be unavailable for it in its: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Nov 28 17:12:28 2009 @@ -140,6 +140,10 @@ Library ------- +- Issue #4486: When an exception has an explicit cause, do not print its + implicit context too. This affects the `traceback` module as well as + built-in exception printing. + - Issue #1515: Enable use of deepcopy() with instance methods. Patch by Robert Collins. Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Sat Nov 28 17:12:28 2009 @@ -1576,7 +1576,7 @@ cause_message, f); } } - if (context) { + else if (context) { res = PySet_Contains(seen, context); if (res == -1) PyErr_Clear(); From python-checkins at python.org Sat Nov 28 17:16:09 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 28 Nov 2009 16:16:09 -0000 Subject: [Python-checkins] r76574 - in python/branches/release31-maint: Lib/test/test_traceback.py Lib/traceback.py Misc/NEWS Python/pythonrun.c Message-ID: Author: antoine.pitrou Date: Sat Nov 28 17:16:09 2009 New Revision: 76574 Log: Merged revisions 76573 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76573 | antoine.pitrou | 2009-11-28 17:12:28 +0100 (sam., 28 nov. 2009) | 3 lines Issue #4486: When an exception has an explicit cause, do not print its implicit context too. ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/test/test_traceback.py python/branches/release31-maint/Lib/traceback.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Python/pythonrun.c Modified: python/branches/release31-maint/Lib/test/test_traceback.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_traceback.py (original) +++ python/branches/release31-maint/Lib/test/test_traceback.py Sat Nov 28 17:16:09 2009 @@ -253,6 +253,26 @@ self.check_zero_div(blocks[0]) self.assertTrue('inner_raise() # Marker' in blocks[2]) + def test_cause_and_context(self): + # When both a cause and a context are set, only the cause should be + # displayed and the context should be muted. + def inner_raise(): + try: + self.zero_div() + except ZeroDivisionError as _e: + e = _e + try: + xyzzy + except NameError: + raise KeyError from e + def outer_raise(): + inner_raise() # Marker + blocks = boundaries.split(self.get_report(outer_raise)) + self.assertEquals(len(blocks), 3) + self.assertEquals(blocks[1], cause_message) + self.check_zero_div(blocks[0]) + self.assert_('inner_raise() # Marker' in blocks[2]) + def test_cause_recursive(self): def inner_raise(): try: Modified: python/branches/release31-maint/Lib/traceback.py ============================================================================== --- python/branches/release31-maint/Lib/traceback.py (original) +++ python/branches/release31-maint/Lib/traceback.py Sat Nov 28 17:16:09 2009 @@ -120,13 +120,14 @@ seen.add(exc) its = [] cause = exc.__cause__ - context = exc.__context__ if cause is not None and cause not in seen: its.append(_iter_chain(cause, None, seen)) its.append([(_cause_message, None)]) - if context is not None and context is not cause and context not in seen: - its.append(_iter_chain(context, None, seen)) - its.append([(_context_message, None)]) + else: + context = exc.__context__ + if context is not None and context not in seen: + its.append(_iter_chain(context, None, seen)) + its.append([(_context_message, None)]) its.append([(exc, custom_tb or exc.__traceback__)]) # itertools.chain is in an extension module and may be unavailable for it in its: Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Sat Nov 28 17:16:09 2009 @@ -49,6 +49,10 @@ Library ------- +- Issue #4486: When an exception has an explicit cause, do not print its + implicit context too. This affects the `traceback` module as well as + built-in exception printing. + - Issue #1488943: difflib.Differ() doesn't always add hints for tab characters - Issue #7354: distutils.tests.test_msvc9compiler - dragfullwindows can Modified: python/branches/release31-maint/Python/pythonrun.c ============================================================================== --- python/branches/release31-maint/Python/pythonrun.c (original) +++ python/branches/release31-maint/Python/pythonrun.c Sat Nov 28 17:16:09 2009 @@ -1576,7 +1576,7 @@ cause_message, f); } } - if (context) { + else if (context) { res = PySet_Contains(seen, context); if (res == -1) PyErr_Clear(); From python-checkins at python.org Sat Nov 28 17:32:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 16:32:27 -0000 Subject: [Python-checkins] r76575 - python/trunk/Python/compile.c Message-ID: Author: mark.dickinson Date: Sat Nov 28 17:32:27 2009 New Revision: 76575 Log: Issue #1678380: When distinguishing between -0.0 and 0.0 in compiler_add_o, use copysign instead of examining the first and last bytes of the double. The latter method fails for little-endian ARM, OABI, where doubles are little-endian but with the words swapped. Modified: python/trunk/Python/compile.c Modified: python/trunk/Python/compile.c ============================================================================== --- python/trunk/Python/compile.c (original) +++ python/trunk/Python/compile.c Sat Nov 28 17:32:27 2009 @@ -910,18 +910,16 @@ { PyObject *t, *v; Py_ssize_t arg; - unsigned char *p; double d; /* necessary to make sure types aren't coerced (e.g., int and long) */ /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ if (PyFloat_Check(o)) { d = PyFloat_AS_DOUBLE(o); - p = (unsigned char*) &d; /* all we need is to make the tuple different in either the 0.0 * or -0.0 case from all others, just to avoid the "coercion". */ - if (*p==0 && p[sizeof(double)-1]==0) + if (d == 0.0 && copysign(1.0, d) < 0.0) t = PyTuple_Pack(3, o, o->ob_type, Py_None); else t = PyTuple_Pack(2, o, o->ob_type); @@ -929,32 +927,23 @@ #ifndef WITHOUT_COMPLEX else if (PyComplex_Check(o)) { Py_complex z; - int real_part_zero, imag_part_zero; - unsigned char *q; - /* complex case is even messier: we need to make complex(x, - 0.) different from complex(x, -0.) and complex(0., y) - different from complex(-0., y), for any x and y. In - particular, all four complex zeros should be - distinguished.*/ + int real_negzero, imag_negzero; + /* For the complex case we must make complex(x, 0.) + different from complex(x, -0.) and complex(0., y) + different from complex(-0., y), for any x and y. + All four complex zeros must be distinguished.*/ z = PyComplex_AsCComplex(o); - p = (unsigned char*) &(z.real); - q = (unsigned char*) &(z.imag); - /* all that matters here is that on IEEE platforms - real_part_zero will be true if z.real == 0., and false if - z.real == -0. In fact, real_part_zero will also be true - for some other rarely occurring nonzero floats, but this - doesn't matter. Similar comments apply to - imag_part_zero. */ - real_part_zero = *p==0 && p[sizeof(double)-1]==0; - imag_part_zero = *q==0 && q[sizeof(double)-1]==0; - if (real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True); + real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; + imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; + if (real_negzero && imag_negzero) { + t = PyTuple_Pack(5, o, o->ob_type, + Py_None, Py_None, Py_None); } - else if (real_part_zero && !imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False); + else if (imag_negzero) { + t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); } - else if (!real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True); + else if (real_negzero) { + t = PyTuple_Pack(3, o, o->ob_type, Py_None); } else { t = PyTuple_Pack(2, o, o->ob_type); From python-checkins at python.org Sat Nov 28 17:37:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 16:37:37 -0000 Subject: [Python-checkins] r76576 - in python/branches/release26-maint: Python/compile.c Message-ID: Author: mark.dickinson Date: Sat Nov 28 17:37:36 2009 New Revision: 76576 Log: Merged revisions 76575 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76575 | mark.dickinson | 2009-11-28 16:32:27 +0000 (Sat, 28 Nov 2009) | 5 lines Issue #1678380: When distinguishing between -0.0 and 0.0 in compiler_add_o, use copysign instead of examining the first and last bytes of the double. The latter method fails for little-endian ARM, OABI, where doubles are little-endian but with the words swapped. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Python/compile.c Modified: python/branches/release26-maint/Python/compile.c ============================================================================== --- python/branches/release26-maint/Python/compile.c (original) +++ python/branches/release26-maint/Python/compile.c Sat Nov 28 17:37:36 2009 @@ -922,18 +922,16 @@ { PyObject *t, *v; Py_ssize_t arg; - unsigned char *p; double d; /* necessary to make sure types aren't coerced (e.g., int and long) */ /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ if (PyFloat_Check(o)) { d = PyFloat_AS_DOUBLE(o); - p = (unsigned char*) &d; /* all we need is to make the tuple different in either the 0.0 * or -0.0 case from all others, just to avoid the "coercion". */ - if (*p==0 && p[sizeof(double)-1]==0) + if (d == 0.0 && copysign(1.0, d) < 0.0) t = PyTuple_Pack(3, o, o->ob_type, Py_None); else t = PyTuple_Pack(2, o, o->ob_type); @@ -941,32 +939,23 @@ #ifndef WITHOUT_COMPLEX else if (PyComplex_Check(o)) { Py_complex z; - int real_part_zero, imag_part_zero; - unsigned char *q; - /* complex case is even messier: we need to make complex(x, - 0.) different from complex(x, -0.) and complex(0., y) - different from complex(-0., y), for any x and y. In - particular, all four complex zeros should be - distinguished.*/ + int real_negzero, imag_negzero; + /* For the complex case we must make complex(x, 0.) + different from complex(x, -0.) and complex(0., y) + different from complex(-0., y), for any x and y. + All four complex zeros must be distinguished.*/ z = PyComplex_AsCComplex(o); - p = (unsigned char*) &(z.real); - q = (unsigned char*) &(z.imag); - /* all that matters here is that on IEEE platforms - real_part_zero will be true if z.real == 0., and false if - z.real == -0. In fact, real_part_zero will also be true - for some other rarely occurring nonzero floats, but this - doesn't matter. Similar comments apply to - imag_part_zero. */ - real_part_zero = *p==0 && p[sizeof(double)-1]==0; - imag_part_zero = *q==0 && q[sizeof(double)-1]==0; - if (real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True); + real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; + imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; + if (real_negzero && imag_negzero) { + t = PyTuple_Pack(5, o, o->ob_type, + Py_None, Py_None, Py_None); } - else if (real_part_zero && !imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False); + else if (imag_negzero) { + t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); } - else if (!real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True); + else if (real_negzero) { + t = PyTuple_Pack(3, o, o->ob_type, Py_None); } else { t = PyTuple_Pack(2, o, o->ob_type); From python-checkins at python.org Sat Nov 28 17:38:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 16:38:16 -0000 Subject: [Python-checkins] r76577 - in python/branches/py3k: Python/compile.c Message-ID: Author: mark.dickinson Date: Sat Nov 28 17:38:16 2009 New Revision: 76577 Log: Merged revisions 76575 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76575 | mark.dickinson | 2009-11-28 16:32:27 +0000 (Sat, 28 Nov 2009) | 5 lines Issue #1678380: When distinguishing between -0.0 and 0.0 in compiler_add_o, use copysign instead of examining the first and last bytes of the double. The latter method fails for little-endian ARM, OABI, where doubles are little-endian but with the words swapped. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Python/compile.c Modified: python/branches/py3k/Python/compile.c ============================================================================== --- python/branches/py3k/Python/compile.c (original) +++ python/branches/py3k/Python/compile.c Sat Nov 28 17:38:16 2009 @@ -895,50 +895,39 @@ { PyObject *t, *v; Py_ssize_t arg; - unsigned char *p; double d; /* necessary to make sure types aren't coerced (e.g., int and long) */ /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ if (PyFloat_Check(o)) { d = PyFloat_AS_DOUBLE(o); - p = (unsigned char*) &d; /* all we need is to make the tuple different in either the 0.0 * or -0.0 case from all others, just to avoid the "coercion". */ - if (*p==0 && p[sizeof(double)-1]==0) + if (d == 0.0 && copysign(1.0, d) < 0.0) t = PyTuple_Pack(3, o, o->ob_type, Py_None); else t = PyTuple_Pack(2, o, o->ob_type); } else if (PyComplex_Check(o)) { Py_complex z; - int real_part_zero, imag_part_zero; - unsigned char *q; - /* complex case is even messier: we need to make complex(x, - 0.) different from complex(x, -0.) and complex(0., y) - different from complex(-0., y), for any x and y. In - particular, all four complex zeros should be - distinguished.*/ + int real_negzero, imag_negzero; + /* For the complex case we must make complex(x, 0.) + different from complex(x, -0.) and complex(0., y) + different from complex(-0., y), for any x and y. + All four complex zeros must be distinguished.*/ z = PyComplex_AsCComplex(o); - p = (unsigned char*) &(z.real); - q = (unsigned char*) &(z.imag); - /* all that matters here is that on IEEE platforms - real_part_zero will be true if z.real == 0., and false if - z.real == -0. In fact, real_part_zero will also be true - for some other rarely occurring nonzero floats, but this - doesn't matter. Similar comments apply to - imag_part_zero. */ - real_part_zero = *p==0 && p[sizeof(double)-1]==0; - imag_part_zero = *q==0 && q[sizeof(double)-1]==0; - if (real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True); + real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; + imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; + if (real_negzero && imag_negzero) { + t = PyTuple_Pack(5, o, o->ob_type, + Py_None, Py_None, Py_None); } - else if (real_part_zero && !imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False); + else if (imag_negzero) { + t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); } - else if (!real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True); + else if (real_negzero) { + t = PyTuple_Pack(3, o, o->ob_type, Py_None); } else { t = PyTuple_Pack(2, o, o->ob_type); From python-checkins at python.org Sat Nov 28 17:39:12 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 28 Nov 2009 16:39:12 -0000 Subject: [Python-checkins] r76578 - in python/branches/release31-maint: Python/compile.c Message-ID: Author: mark.dickinson Date: Sat Nov 28 17:39:12 2009 New Revision: 76578 Log: Merged revisions 76577 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r76577 | mark.dickinson | 2009-11-28 16:38:16 +0000 (Sat, 28 Nov 2009) | 12 lines Merged revisions 76575 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76575 | mark.dickinson | 2009-11-28 16:32:27 +0000 (Sat, 28 Nov 2009) | 5 lines Issue #1678380: When distinguishing between -0.0 and 0.0 in compiler_add_o, use copysign instead of examining the first and last bytes of the double. The latter method fails for little-endian ARM, OABI, where doubles are little-endian but with the words swapped. ........ ................ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Python/compile.c Modified: python/branches/release31-maint/Python/compile.c ============================================================================== --- python/branches/release31-maint/Python/compile.c (original) +++ python/branches/release31-maint/Python/compile.c Sat Nov 28 17:39:12 2009 @@ -909,18 +909,16 @@ { PyObject *t, *v; Py_ssize_t arg; - unsigned char *p; double d; /* necessary to make sure types aren't coerced (e.g., int and long) */ /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ if (PyFloat_Check(o)) { d = PyFloat_AS_DOUBLE(o); - p = (unsigned char*) &d; /* all we need is to make the tuple different in either the 0.0 * or -0.0 case from all others, just to avoid the "coercion". */ - if (*p==0 && p[sizeof(double)-1]==0) + if (d == 0.0 && copysign(1.0, d) < 0.0) t = PyTuple_Pack(3, o, o->ob_type, Py_None); else t = PyTuple_Pack(2, o, o->ob_type); @@ -928,32 +926,23 @@ #ifndef WITHOUT_COMPLEX else if (PyComplex_Check(o)) { Py_complex z; - int real_part_zero, imag_part_zero; - unsigned char *q; - /* complex case is even messier: we need to make complex(x, - 0.) different from complex(x, -0.) and complex(0., y) - different from complex(-0., y), for any x and y. In - particular, all four complex zeros should be - distinguished.*/ + int real_negzero, imag_negzero; + /* For the complex case we must make complex(x, 0.) + different from complex(x, -0.) and complex(0., y) + different from complex(-0., y), for any x and y. + All four complex zeros must be distinguished.*/ z = PyComplex_AsCComplex(o); - p = (unsigned char*) &(z.real); - q = (unsigned char*) &(z.imag); - /* all that matters here is that on IEEE platforms - real_part_zero will be true if z.real == 0., and false if - z.real == -0. In fact, real_part_zero will also be true - for some other rarely occurring nonzero floats, but this - doesn't matter. Similar comments apply to - imag_part_zero. */ - real_part_zero = *p==0 && p[sizeof(double)-1]==0; - imag_part_zero = *q==0 && q[sizeof(double)-1]==0; - if (real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_True); + real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; + imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; + if (real_negzero && imag_negzero) { + t = PyTuple_Pack(5, o, o->ob_type, + Py_None, Py_None, Py_None); } - else if (real_part_zero && !imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_True, Py_False); + else if (imag_negzero) { + t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); } - else if (!real_part_zero && imag_part_zero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_False, Py_True); + else if (real_negzero) { + t = PyTuple_Pack(3, o, o->ob_type, Py_None); } else { t = PyTuple_Pack(2, o, o->ob_type); From solipsis at pitrou.net Sun Nov 29 00:47:34 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 29 Nov 2009 00:47:34 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76577): sum=12 Message-ID: <20091128234734.CEBD917759@ns6635.ovh.net> py3k results for svn r76577 (hg cset 946d2464c32c) -------------------------------------------------- test_urllib leaked [6, 4, 2] references, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogBVuqKS', '-x', 'test_httpservers'] From python-checkins at python.org Sun Nov 29 09:50:40 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 29 Nov 2009 08:50:40 -0000 Subject: [Python-checkins] r76582 - tracker/roundup-src/roundup/cgi/templating.py Message-ID: Author: martin.v.loewis Date: Sun Nov 29 09:50:40 2009 New Revision: 76582 Log: Patch from Richard Jones for issue 2550549. Modified: tracker/roundup-src/roundup/cgi/templating.py Modified: tracker/roundup-src/roundup/cgi/templating.py ============================================================================== --- tracker/roundup-src/roundup/cgi/templating.py (original) +++ tracker/roundup-src/roundup/cgi/templating.py Sun Nov 29 09:50:40 2009 @@ -1353,9 +1353,12 @@ elif match.group('email'): s = match.group('email') return '%s'%(s, s) - else: + elif len(match.group('id')) < 10: return self._hyper_repl_item(match, '%(item)s') + else: + # just return the matched text + return match.group(0) def _hyper_repl_rst(self, match): if match.group('url'): @@ -1364,8 +1367,11 @@ elif match.group('email'): s = match.group('email') return '`%s `_'%(s, s) - else: + elif len(match.group('id')) < 10: return self._hyper_repl_item(match,'`%(item)s <%(cls)s%(id)s>`_') + else: + # just return the matched text + return match.group(0) def hyperlinked(self): """ Render a "hyperlinked" version of the text """ From python-checkins at python.org Sun Nov 29 18:40:57 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 29 Nov 2009 17:40:57 -0000 Subject: [Python-checkins] r76583 - in python/trunk: Lib/test/formatfloat_testcases.txt Lib/test/test_complex.py Lib/test/test_float.py Misc/NEWS Objects/stringlib/formatter.h Objects/stringobject.c Objects/unicodeobject.c Message-ID: Author: eric.smith Date: Sun Nov 29 18:40:57 2009 New Revision: 76583 Log: Issue #3382: Make '%F' and float.__format__('F') convert results to upper case. Much of the patch came from Mark Dickinson. Modified: python/trunk/Lib/test/formatfloat_testcases.txt python/trunk/Lib/test/test_complex.py python/trunk/Lib/test/test_float.py python/trunk/Misc/NEWS python/trunk/Objects/stringlib/formatter.h python/trunk/Objects/stringobject.c python/trunk/Objects/unicodeobject.c Modified: python/trunk/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/trunk/Lib/test/formatfloat_testcases.txt (original) +++ python/trunk/Lib/test/formatfloat_testcases.txt Sun Nov 29 18:40:57 2009 @@ -81,6 +81,14 @@ %f 0.0000005001 -> 0.000001 %f 0.0000004999 -> 0.000000 +-- nans and infinities +%f nan -> nan +%f inf -> inf +%f -infinity -> -inf +%F nan -> NAN +%F infinity -> INF +%F -inf -> -INF + -- 'e' code formatting with explicit precision (>= 0). Output should -- always have exactly the number of places after the point that were -- requested. @@ -202,6 +210,14 @@ %#.1e 123.4 -> 1.2e+02 %#.2e 0.0001357 -> 1.36e-04 +-- nans and infinities +%e nan -> nan +%e inf -> inf +%e -infinity -> -inf +%E nan -> NAN +%E infinity -> INF +%E -inf -> -INF + -- 'g' code formatting. -- zeros @@ -314,6 +330,14 @@ %#.5g 234.56 -> 234.56 %#.6g 234.56 -> 234.560 +-- nans and infinities +%g nan -> nan +%g inf -> inf +%g -infinity -> -inf +%G nan -> NAN +%G infinity -> INF +%G -inf -> -INF + -- for repr formatting see the separate test_short_repr test in -- test_float.py. Not all platforms use short repr for floats. Modified: python/trunk/Lib/test/test_complex.py ============================================================================== --- python/trunk/Lib/test/test_complex.py (original) +++ python/trunk/Lib/test/test_complex.py Sun Nov 29 18:40:57 2009 @@ -539,6 +539,25 @@ # make sure everything works in ''.format() self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') + # issue 3382: 'f' and 'F' with inf's and nan's + self.assertEqual('{0:f}'.format(INF+0j), 'inf+0.000000j') + self.assertEqual('{0:F}'.format(INF+0j), 'INF+0.000000j') + self.assertEqual('{0:f}'.format(-INF+0j), '-inf+0.000000j') + self.assertEqual('{0:F}'.format(-INF+0j), '-INF+0.000000j') + self.assertEqual('{0:f}'.format(complex(INF, INF)), 'inf+infj') + self.assertEqual('{0:F}'.format(complex(INF, INF)), 'INF+INFj') + self.assertEqual('{0:f}'.format(complex(INF, -INF)), 'inf-infj') + self.assertEqual('{0:F}'.format(complex(INF, -INF)), 'INF-INFj') + self.assertEqual('{0:f}'.format(complex(-INF, INF)), '-inf+infj') + self.assertEqual('{0:F}'.format(complex(-INF, INF)), '-INF+INFj') + self.assertEqual('{0:f}'.format(complex(-INF, -INF)), '-inf-infj') + self.assertEqual('{0:F}'.format(complex(-INF, -INF)), '-INF-INFj') + + self.assertEqual('{0:f}'.format(complex(NAN, 0)), 'nan+0.000000j') + self.assertEqual('{0:F}'.format(complex(NAN, 0)), 'NAN+0.000000j') + self.assertEqual('{0:f}'.format(complex(NAN, NAN)), 'nan+nanj') + self.assertEqual('{0:F}'.format(complex(NAN, NAN)), 'NAN+NANj') + def test_main(): test_support.run_unittest(ComplexTest) Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Sun Nov 29 18:40:57 2009 @@ -309,6 +309,14 @@ self.assertRaises(ValueError, format, 1e-100, format_spec) self.assertRaises(ValueError, format, -1e-100, format_spec) + # issue 3382: 'f' and 'F' with inf's and nan's + self.assertEqual('{0:f}'.format(INF), 'inf') + self.assertEqual('{0:F}'.format(INF), 'INF') + self.assertEqual('{0:f}'.format(-INF), '-inf') + self.assertEqual('{0:F}'.format(-INF), '-INF') + self.assertEqual('{0:f}'.format(NAN), 'nan') + self.assertEqual('{0:F}'.format(NAN), 'NAN') + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") def test_format_testfile(self): @@ -321,8 +329,10 @@ lhs, rhs = map(str.strip, line.split('->')) fmt, arg = lhs.split() - self.assertEqual(fmt % float(arg), rhs) - self.assertEqual(fmt % -float(arg), '-' + rhs) + arg = float(arg) + self.assertEqual(fmt % arg, rhs) + if not math.isnan(arg) and copysign(1.0, arg) > 0.0: + self.assertEqual(fmt % -arg, '-' + rhs) def test_issue5864(self): self.assertEquals(format(123.456, '.4'), '123.5') Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 29 18:40:57 2009 @@ -12,6 +12,10 @@ Core and Builtins ----------------- +- Issue #3382: 'F' formatting for float and complex now convert the + result to upper case. This only affects 'inf' and 'nan', since 'f' + no longer converts to 'g' for large values. + - Remove switch from "%f" formatting to "%g" formatting for floats larger than 1e50 in absolute value. Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Sun Nov 29 18:40:57 2009 @@ -937,13 +937,6 @@ format the result. We take care of that later. */ type = 'g'; -#if PY_VERSION_HEX < 0x0301000 - /* 'F' is the same as 'f', per the PEP */ - /* This is no longer the case in 3.x */ - if (type == 'F') - type = 'f'; -#endif - val = PyFloat_AsDouble(value); if (val == -1.0 && PyErr_Occurred()) goto done; @@ -1128,13 +1121,6 @@ format the result. We take care of that later. */ type = 'g'; -#if PY_VERSION_HEX < 0x03010000 - /* This is no longer the case in 3.x */ - /* 'F' is the same as 'f', per the PEP */ - if (type == 'F') - type = 'f'; -#endif - if (precision < 0) precision = default_precision; Modified: python/trunk/Objects/stringobject.c ============================================================================== --- python/trunk/Objects/stringobject.c (original) +++ python/trunk/Objects/stringobject.c Sun Nov 29 18:40:57 2009 @@ -4966,8 +4966,6 @@ case 'F': case 'g': case 'G': - if (c == 'F') - c = 'f'; temp = formatfloat(v, flags, prec, c); if (temp == NULL) goto error; Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Sun Nov 29 18:40:57 2009 @@ -8809,8 +8809,6 @@ case 'F': case 'g': case 'G': - if (c == 'F') - c = 'f'; temp = formatfloat(v, flags, prec, c); if (temp == NULL) goto onError; From python-checkins at python.org Sun Nov 29 18:42:06 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 29 Nov 2009 17:42:06 -0000 Subject: [Python-checkins] r76584 - python/branches/release26-maint Message-ID: Author: eric.smith Date: Sun Nov 29 18:42:05 2009 New Revision: 76584 Log: Blocked revisions 76583 via svnmerge ........ r76583 | eric.smith | 2009-11-29 12:40:57 -0500 (Sun, 29 Nov 2009) | 1 line Issue #3382: Make '%F' and float.__format__('F') convert results to upper case. Much of the patch came from Mark Dickinson. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Nov 29 18:44:41 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 29 Nov 2009 17:44:41 -0000 Subject: [Python-checkins] r76585 - python/branches/py3k Message-ID: Author: eric.smith Date: Sun Nov 29 18:44:41 2009 New Revision: 76585 Log: Blocked revisions 76583 via svnmerge ........ r76583 | eric.smith | 2009-11-29 12:40:57 -0500 (Sun, 29 Nov 2009) | 1 line Issue #3382: Make '%F' and float.__format__('F') convert results to upper case. Much of the patch came from Mark Dickinson. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Nov 29 18:56:55 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 29 Nov 2009 17:56:55 -0000 Subject: [Python-checkins] r76586 - python/branches/py3k/Objects/stringlib/formatter.h Message-ID: Author: eric.smith Date: Sun Nov 29 18:56:54 2009 New Revision: 76586 Log: Keep this file in sync with trunk. Modified: python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Sun Nov 29 18:56:54 2009 @@ -937,13 +937,6 @@ format the result. We take care of that later. */ type = 'g'; -#if PY_VERSION_HEX < 0x0301000 - /* 'F' is the same as 'f', per the PEP */ - /* This is no longer the case in 3.x */ - if (type == 'F') - type = 'f'; -#endif - val = PyFloat_AsDouble(value); if (val == -1.0 && PyErr_Occurred()) goto done; @@ -957,12 +950,6 @@ if (precision < 0) precision = default_precision; -#if PY_VERSION_HEX < 0x03010000 - /* 3.1 no longer converts large 'f' to 'g'. */ - if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) - type = 'g'; -#endif - /* Cast "type", because if we're in unicode we need to pass a 8-bit char. This is safe, because we've restricted what "type" can be. */ @@ -1134,13 +1121,6 @@ format the result. We take care of that later. */ type = 'g'; -#if PY_VERSION_HEX < 0x03010000 - /* This is no longer the case in 3.x */ - /* 'F' is the same as 'f', per the PEP */ - if (type == 'F') - type = 'f'; -#endif - if (precision < 0) precision = default_precision; From python-checkins at python.org Sun Nov 29 18:57:23 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 29 Nov 2009 17:57:23 -0000 Subject: [Python-checkins] r76587 - python/branches/release31-maint Message-ID: Author: eric.smith Date: Sun Nov 29 18:57:23 2009 New Revision: 76587 Log: Blocked revisions 76586 via svnmerge ........ r76586 | eric.smith | 2009-11-29 12:56:54 -0500 (Sun, 29 Nov 2009) | 1 line Keep this file in sync with trunk. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Sun Nov 29 23:20:30 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 29 Nov 2009 22:20:30 -0000 Subject: [Python-checkins] r76588 - in python/trunk: Lib/distutils/tests/test_sdist.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Sun Nov 29 23:20:30 2009 New Revision: 76588 Log: Fixed #7408: dropped group ownership checking because it relies on os-specific rules Modified: python/trunk/Lib/distutils/tests/test_sdist.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_sdist.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_sdist.py (original) +++ python/trunk/Lib/distutils/tests/test_sdist.py Sun Nov 29 23:20:30 2009 @@ -336,10 +336,13 @@ # making sure we have the good rights archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') archive = tarfile.open(archive_name) + + # note that we are not testing the group ownership here + # because, depending on the platforms and the container + # rights (see #7408) try: for member in archive.getmembers(): self.assertEquals(member.uid, os.getuid()) - self.assertEquals(member.gid, os.getgid()) finally: archive.close() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Nov 29 23:20:30 2009 @@ -487,6 +487,10 @@ Library ------- +- Issue #7408: Fixed distutils.tests.sdist so it doesn't check for group + ownership when the group is not forced, because the group may be different + from the user's group and inherit from its container when the test is run. + - Issue #1515: Enable use of deepcopy() with instance methods. Patch by Robert Collins. From python-checkins at python.org Sun Nov 29 23:22:40 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 29 Nov 2009 22:22:40 -0000 Subject: [Python-checkins] r76589 - python/branches/release26-maint Message-ID: Author: tarek.ziade Date: Sun Nov 29 23:22:40 2009 New Revision: 76589 Log: Blocked revisions 76588 via svnmerge ........ r76588 | tarek.ziade | 2009-11-29 23:20:30 +0100 (Sun, 29 Nov 2009) | 1 line Fixed #7408: dropped group ownership checking because it relies on os-specific rules ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Nov 29 23:24:57 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 29 Nov 2009 22:24:57 -0000 Subject: [Python-checkins] r76590 - in python/branches/py3k: Lib/distutils/tests/test_sdist.py Misc/NEWS Message-ID: Author: tarek.ziade Date: Sun Nov 29 23:24:57 2009 New Revision: 76590 Log: Merged revisions 76588 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76588 | tarek.ziade | 2009-11-29 23:20:30 +0100 (Sun, 29 Nov 2009) | 1 line Fixed #7408: dropped group ownership checking because it relies on os-specific rules ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_sdist.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_sdist.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_sdist.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_sdist.py Sun Nov 29 23:24:57 2009 @@ -336,10 +336,13 @@ # making sure we have the good rights archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') archive = tarfile.open(archive_name) + + # note that we are not testing the group ownership here + # because, depending on the platforms and the container + # rights (see #7408) try: for member in archive.getmembers(): self.assertEquals(member.uid, os.getuid()) - self.assertEquals(member.gid, os.getgid()) finally: archive.close() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Nov 29 23:24:57 2009 @@ -140,6 +140,10 @@ Library ------- +- Issue #7408: Fixed distutils.tests.sdist so it doesn't check for group + ownership when the group is not forced, because the group may be different + from the user's group and inherit from its container when the test is run. + - Issue #4486: When an exception has an explicit cause, do not print its implicit context too. This affects the `traceback` module as well as built-in exception printing. From python-checkins at python.org Sun Nov 29 23:26:26 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 29 Nov 2009 22:26:26 -0000 Subject: [Python-checkins] r76591 - python/trunk/Lib/unittest/case.py Message-ID: Author: benjamin.peterson Date: Sun Nov 29 23:26:26 2009 New Revision: 76591 Log: now that deepcopy can handle instance methods, this hack can be removed #7409 Thanks Robert Collins Modified: python/trunk/Lib/unittest/case.py Modified: python/trunk/Lib/unittest/case.py ============================================================================== --- python/trunk/Lib/unittest/case.py (original) +++ python/trunk/Lib/unittest/case.py Sun Nov 29 23:26:26 2009 @@ -117,17 +117,6 @@ return True -class _AssertWrapper(object): - """Wrap entries in the _type_equality_funcs registry to make them deep - copyable.""" - - def __init__(self, function): - self.function = function - - def __deepcopy__(self, memo): - memo[id(self)] = self - - class TestCase(object): """A class whose instances are single test cases. @@ -201,7 +190,7 @@ msg= argument that raises self.failureException with a useful error message when the two arguments are not equal. """ - self._type_equality_funcs[typeobj] = _AssertWrapper(function) + self._type_equality_funcs[typeobj] = function def addCleanup(self, function, *args, **kwargs): """Add a function, with arguments, to be called when the test is @@ -424,7 +413,7 @@ if type(first) is type(second): asserter = self._type_equality_funcs.get(type(first)) if asserter is not None: - return asserter.function + return asserter return self._baseAssertEqual From python-checkins at python.org Sun Nov 29 23:30:27 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 29 Nov 2009 22:30:27 -0000 Subject: [Python-checkins] r76592 - python/branches/release31-maint Message-ID: Author: tarek.ziade Date: Sun Nov 29 23:30:27 2009 New Revision: 76592 Log: Blocked revisions 76590 via svnmerge ................ r76590 | tarek.ziade | 2009-11-29 23:24:57 +0100 (Sun, 29 Nov 2009) | 9 lines Merged revisions 76588 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r76588 | tarek.ziade | 2009-11-29 23:20:30 +0100 (Sun, 29 Nov 2009) | 1 line Fixed #7408: dropped group ownership checking because it relies on os-specific rules ........ ................ Modified: python/branches/release31-maint/ (props changed) From solipsis at pitrou.net Mon Nov 30 00:50:11 2009 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 30 Nov 2009 00:50:11 +0100 (CET) Subject: [Python-checkins] Daily py3k reference leaks (r76586): sum=10 Message-ID: <20091129235011.A41AE17714@ns6635.ovh.net> py3k results for svn r76586 (hg cset bc2a0ddbfbda) -------------------------------------------------- test_urllib leaked [4, 4, 2] references, sum=10 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogGKJHRB', '-x', 'test_httpservers'] From python-checkins at python.org Mon Nov 30 01:08:56 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Mon, 30 Nov 2009 00:08:56 -0000 Subject: [Python-checkins] r76593 - in python/branches/py3k: Lib/tempfile.py Lib/test/test_tempfile.py Misc/NEWS Message-ID: Author: amaury.forgeotdarc Date: Mon Nov 30 01:08:56 2009 New Revision: 76593 Log: #6077: on Windows, fix truncation of a tempfile.TemporaryFile opened in "wt+" mode: files opened with os.open() stop on the first \x1a (Ctrl-Z) unless os.O_BINARY is used. Will backport to 3.1 Modified: python/branches/py3k/Lib/tempfile.py python/branches/py3k/Lib/test/test_tempfile.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/tempfile.py ============================================================================== --- python/branches/py3k/Lib/tempfile.py (original) +++ python/branches/py3k/Lib/tempfile.py Mon Nov 30 01:08:56 2009 @@ -169,7 +169,6 @@ namer = _RandomNameSequence() dirlist = _candidate_tempdir_list() - flags = _text_openflags for dir in dirlist: if dir != _os.curdir: @@ -179,7 +178,7 @@ name = next(namer) filename = _os.path.join(dir, name) try: - fd = _os.open(filename, flags, 0o600) + fd = _os.open(filename, _bin_openflags, 0o600) fp = _io.open(fd, 'wb') fp.write(b'blat') fp.close() @@ -434,10 +433,7 @@ if dir is None: dir = gettempdir() - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags + flags = _bin_openflags # Setting O_TEMPORARY in the flags causes the OS to delete # the file when it is closed. This is only supported by Windows. @@ -475,10 +471,7 @@ if dir is None: dir = gettempdir() - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags + flags = _bin_openflags (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) try: Modified: python/branches/py3k/Lib/test/test_tempfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tempfile.py (original) +++ python/branches/py3k/Lib/test/test_tempfile.py Mon Nov 30 01:08:56 2009 @@ -309,8 +309,12 @@ if not has_textmode: return # ugh, can't use SkipTest. - self.do_create(bin=0).write(b"blat\n") - # XXX should test that the file really is a text file + # A text file is truncated at the first Ctrl+Z byte + f = self.do_create(bin=0) + f.write(b"blat\x1a") + f.write(b"extra\n") + os.lseek(f.fd, 0, os.SEEK_SET) + self.assertEquals(os.read(f.fd, 20), b"blat") test_classes.append(test__mkstemp_inner) @@ -761,6 +765,10 @@ f.write("xyzzy\n") f.seek(0) self.assertEqual(f.read(), "abc\ndef\nxyzzy\n") + # Check that Ctrl+Z doesn't truncate the file + f.write("foo\x1abar\n") + f.seek(0) + self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Nov 30 01:08:56 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #6077: On Windows, files opened with tempfile.TemporaryFile in "wt+" + mode would appear truncated on the first '0x1a' byte (aka. Ctrl+Z). + - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. From python-checkins at python.org Mon Nov 30 01:16:44 2009 From: python-checkins at python.org (amaury.forgeotdarc) Date: Mon, 30 Nov 2009 00:16:44 -0000 Subject: [Python-checkins] r76594 - in python/branches/release31-maint: Lib/tempfile.py Lib/test/test_tempfile.py Misc/NEWS Message-ID: Author: amaury.forgeotdarc Date: Mon Nov 30 01:16:44 2009 New Revision: 76594 Log: Merged revisions 76593 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r76593 | amaury.forgeotdarc | 2009-11-30 01:08:56 +0100 (lun., 30 nov. 2009) | 5 lines #6077: on Windows, fix truncation of a tempfile.TemporaryFile opened in "wt+" mode: files opened with os.open() stop on the first \x1a (Ctrl-Z) unless os.O_BINARY is used. Will backport to 3.1 ........ Modified: python/branches/release31-maint/ (props changed) python/branches/release31-maint/Lib/tempfile.py python/branches/release31-maint/Lib/test/test_tempfile.py python/branches/release31-maint/Misc/NEWS Modified: python/branches/release31-maint/Lib/tempfile.py ============================================================================== --- python/branches/release31-maint/Lib/tempfile.py (original) +++ python/branches/release31-maint/Lib/tempfile.py Mon Nov 30 01:16:44 2009 @@ -169,7 +169,6 @@ namer = _RandomNameSequence() dirlist = _candidate_tempdir_list() - flags = _text_openflags for dir in dirlist: if dir != _os.curdir: @@ -179,7 +178,7 @@ name = next(namer) filename = _os.path.join(dir, name) try: - fd = _os.open(filename, flags, 0o600) + fd = _os.open(filename, _bin_openflags, 0o600) fp = _io.open(fd, 'wb') fp.write(b'blat') fp.close() @@ -434,10 +433,7 @@ if dir is None: dir = gettempdir() - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags + flags = _bin_openflags # Setting O_TEMPORARY in the flags causes the OS to delete # the file when it is closed. This is only supported by Windows. @@ -475,10 +471,7 @@ if dir is None: dir = gettempdir() - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags + flags = _bin_openflags (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) try: Modified: python/branches/release31-maint/Lib/test/test_tempfile.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_tempfile.py (original) +++ python/branches/release31-maint/Lib/test/test_tempfile.py Mon Nov 30 01:16:44 2009 @@ -309,8 +309,12 @@ if not has_textmode: return # ugh, can't use SkipTest. - self.do_create(bin=0).write(b"blat\n") - # XXX should test that the file really is a text file + # A text file is truncated at the first Ctrl+Z byte + f = self.do_create(bin=0) + f.write(b"blat\x1a") + f.write(b"extra\n") + os.lseek(f.fd, 0, os.SEEK_SET) + self.assertEquals(os.read(f.fd, 20), b"blat") test_classes.append(test__mkstemp_inner) @@ -761,6 +765,10 @@ f.write("xyzzy\n") f.seek(0) self.assertEqual(f.read(), "abc\ndef\nxyzzy\n") + # Check that Ctrl+Z doesn't truncate the file + f.write("foo\x1abar\n") + f.seek(0) + self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n") def test_text_newline_and_encoding(self): f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10, Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Nov 30 01:16:44 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #6077: On Windows, files opened with tempfile.TemporaryFile in "wt+" + mode would appear truncated on the first '0x1a' byte (aka. Ctrl+Z). + - Issue #7085: Fix crash when importing some extensions in a thread on MacOSX 10.6. From nnorwitz at gmail.com Mon Nov 30 01:15:56 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 29 Nov 2009 19:15:56 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20091130001556.GA3117@kbk-i386-bb.psfb.org> More important issues: ---------------------- test_bz2 leaked [0, 0, 82] references, sum=82 test_distutils leaked [-25, 0, 0] references, sum=-25 Less important issues: ---------------------- test_cmd_line leaked [-25, 25, 0] references, sum=0 test_popen2 leaked [-29, 0, -25] references, sum=-54 test_ssl leaked [26, -26, 0] references, sum=0 From python-checkins at python.org Mon Nov 30 02:01:43 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 30 Nov 2009 01:01:43 -0000 Subject: [Python-checkins] r76595 - in python/branches/py3k/Objects: bytesobject.c stringlib/stringdefs.h stringlib/unicodedefs.h Message-ID: Author: eric.smith Date: Mon Nov 30 02:01:42 2009 New Revision: 76595 Log: Issue #5748: bytesobject.c should not have its own private defines for stringlib macros. Also removed used defines and include for localutil.h. Modified: python/branches/py3k/Objects/bytesobject.c python/branches/py3k/Objects/stringlib/stringdefs.h python/branches/py3k/Objects/stringlib/unicodedefs.h Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Mon Nov 30 02:01:42 2009 @@ -563,29 +563,15 @@ /* Methods */ #include "stringlib/stringdefs.h" -#define STRINGLIB_CHAR char - -#define STRINGLIB_CMP memcmp -#define STRINGLIB_LEN PyBytes_GET_SIZE -#define STRINGLIB_NEW PyBytes_FromStringAndSize -#define STRINGLIB_STR PyBytes_AS_STRING -/* #define STRINGLIB_WANT_CONTAINS_OBJ 1 */ - -#define STRINGLIB_EMPTY nullstring -#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact -#define STRINGLIB_MUTABLE 0 #include "stringlib/fastsearch.h" - #include "stringlib/count.h" #include "stringlib/find.h" #include "stringlib/partition.h" #include "stringlib/ctype.h" -#include "stringlib/transmogrify.h" -#define _Py_InsertThousandsGrouping _PyBytes_InsertThousandsGrouping -#define _Py_InsertThousandsGroupingLocale _PyBytes_InsertThousandsGroupingLocale -#include "stringlib/localeutil.h" +#define STRINGLIB_MUTABLE 0 +#include "stringlib/transmogrify.h" PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) Modified: python/branches/py3k/Objects/stringlib/stringdefs.h ============================================================================== --- python/branches/py3k/Objects/stringlib/stringdefs.h (original) +++ python/branches/py3k/Objects/stringlib/stringdefs.h Mon Nov 30 02:01:42 2009 @@ -21,6 +21,7 @@ #define STRINGLIB_NEW PyBytes_FromStringAndSize #define STRINGLIB_RESIZE _PyBytes_Resize #define STRINGLIB_CHECK PyBytes_Check +#define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping Modified: python/branches/py3k/Objects/stringlib/unicodedefs.h ============================================================================== --- python/branches/py3k/Objects/stringlib/unicodedefs.h (original) +++ python/branches/py3k/Objects/stringlib/unicodedefs.h Mon Nov 30 02:01:42 2009 @@ -21,6 +21,7 @@ #define STRINGLIB_NEW PyUnicode_FromUnicode #define STRINGLIB_RESIZE PyUnicode_Resize #define STRINGLIB_CHECK PyUnicode_Check +#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping #define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale From python-checkins at python.org Mon Nov 30 02:03:20 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 30 Nov 2009 01:03:20 -0000 Subject: [Python-checkins] r76596 - python/branches/release31-maint Message-ID: Author: eric.smith Date: Mon Nov 30 02:03:20 2009 New Revision: 76596 Log: Blocked revisions 76595 via svnmerge ........ r76595 | eric.smith | 2009-11-29 20:01:42 -0500 (Sun, 29 Nov 2009) | 1 line Issue #5748: bytesobject.c should not have its own private defines for stringlib macros. Also removed used defines and include for localutil.h. ........ Modified: python/branches/release31-maint/ (props changed) From python-checkins at python.org Mon Nov 30 03:04:18 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 30 Nov 2009 02:04:18 -0000 Subject: [Python-checkins] r76595 - svn:log Message-ID: Author: eric.smith Revision: 76595 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Issue #5748: bytesobject.c should not have its own private defines for stringlib macros. Also removed used defines and include for localutil.h. \ No newline at end of file +Issue #5748: bytesobject.c should not have its own private defines for stringlib macros. Also removed unused defines and include for localutil.h. \ No newline at end of file From python-checkins at python.org Mon Nov 30 12:15:29 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 11:15:29 -0000 Subject: [Python-checkins] r76599 - in python/branches/release26-maint: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Mon Nov 30 12:15:28 2009 New Revision: 76599 Log: Issue #7410: deepcopy of itertools.count() erroneously reset the count. Modified: python/branches/release26-maint/Lib/test/test_itertools.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/itertoolsmodule.c Modified: python/branches/release26-maint/Lib/test/test_itertools.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_itertools.py (original) +++ python/branches/release26-maint/Lib/test/test_itertools.py Mon Nov 30 12:15:28 2009 @@ -5,6 +5,8 @@ import sys import operator import random +import copy +import pickle maxsize = test_support.MAX_Py_ssize_t minsize = -maxsize-1 @@ -215,6 +217,13 @@ r2 = 'count(%r)'.__mod__(i).replace('L', '') self.assertEqual(r1, r2) + # check copy, deepcopy, pickle + for value in -3, 3, sys.maxint-5, sys.maxint+5: + c = count(value) + self.assertEqual(next(copy.copy(c)), value) + self.assertEqual(next(copy.deepcopy(c)), value) + self.assertEqual(next(pickle.loads(pickle.dumps(c))), value) + def test_cycle(self): self.assertEqual(take(10, cycle('abc')), list('abcabcabca')) self.assertEqual(list(cycle('')), []) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Nov 30 12:15:28 2009 @@ -33,6 +33,8 @@ Library ------- +- Issue #7410: deepcopy of itertools.count() erroneously reset the count. + - Issue #7403: logging: Fixed possible race condition in lock creation. - Issue #7341: Close the internal file object in the TarFile constructor in Modified: python/branches/release26-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release26-maint/Modules/itertoolsmodule.c Mon Nov 30 12:15:28 2009 @@ -2906,6 +2906,21 @@ return result; } +static PyObject * +count_reduce(countobject *lz) +{ + if (lz->cnt == PY_SSIZE_T_MAX) + return Py_BuildValue("O(O)", Py_TYPE(lz), lz->long_cnt); + return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); +} + +PyDoc_STRVAR(count_reduce_doc, "Return state information for pickling."); + +static PyMethodDef count_methods[] = { + {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, + count_reduce_doc}, +}; + PyDoc_STRVAR(count_doc, "count([firstval]) --> count object\n\ \n\ @@ -2941,7 +2956,7 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ - 0, /* tp_methods */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ From python-checkins at python.org Mon Nov 30 20:44:40 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 19:44:40 -0000 Subject: [Python-checkins] r76600 - in python/trunk: Lib/test/test_itertools.py Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Mon Nov 30 20:44:40 2009 New Revision: 76600 Log: Issue 7410: deepcopy of itertools.count resets the count Modified: python/trunk/Lib/test/test_itertools.py python/trunk/Modules/itertoolsmodule.c Modified: python/trunk/Lib/test/test_itertools.py ============================================================================== --- python/trunk/Lib/test/test_itertools.py (original) +++ python/trunk/Lib/test/test_itertools.py Mon Nov 30 20:44:40 2009 @@ -7,6 +7,8 @@ import sys import operator import random +import copy +import pickle maxsize = test_support.MAX_Py_ssize_t minsize = -maxsize-1 @@ -346,6 +348,13 @@ r2 = 'count(%r)'.__mod__(i).replace('L', '') self.assertEqual(r1, r2) + # check copy, deepcopy, pickle + for value in -3, 3, sys.maxint-5, sys.maxint+5: + c = count(value) + self.assertEqual(next(copy.copy(c)), value) + self.assertEqual(next(copy.deepcopy(c)), value) + self.assertEqual(next(pickle.loads(pickle.dumps(c))), value) + def test_count_with_stride(self): self.assertEqual(zip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)]) self.assertEqual(zip('abc',count(start=2,step=3)), Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Mon Nov 30 20:44:40 2009 @@ -3375,6 +3375,21 @@ return result; } +static PyObject * +count_reduce(countobject *lz) +{ + if (lz->cnt == PY_SSIZE_T_MAX) + return Py_BuildValue("O(O)", Py_TYPE(lz), lz->long_cnt); + return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); +} + +PyDoc_STRVAR(count_reduce_doc, "Return state information for pickling."); + +static PyMethodDef count_methods[] = { + {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, + count_reduce_doc}, +}; + PyDoc_STRVAR(count_doc, "count(start=0, step=1]) --> count object\n\ \n\ @@ -3416,7 +3431,7 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ - 0, /* tp_methods */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ From python-checkins at python.org Mon Nov 30 21:54:20 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 30 Nov 2009 20:54:20 -0000 Subject: [Python-checkins] r76601 - python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py Message-ID: Author: tarek.ziade Date: Mon Nov 30 21:54:20 2009 New Revision: 76601 Log: python_build will trigger a deprecation warning now Modified: python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py Modified: python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py ============================================================================== --- python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py (original) +++ python/branches/tarek_sysconfig/Lib/distutils/sysconfig.py Mon Nov 30 21:54:20 2009 @@ -77,27 +77,24 @@ # The rest of this module is deprecated. will go away # in Python 2.8/3.3 # -class _DeprecatedString(str): - pass - # XXX how do I send a deprecation warning here ?? +_DEPRECATION_MSG = ("distutils.sysconfig.%s is deprecated. " + "Use the APIs provided by the sysconfig module instead") def _get_project_base(): - return _DeprecatedString(_sysconfig._PROJECT_BASE) + return _sysconfig._PROJECT_BASE project_base = _get_project_base() class _DeprecatedBool(int): - pass - # XXX how do I send a deprecation warning here ?? + def __nonzero__(self): + warn(_DEPRECATION_MSG % 'get_python_version', DeprecationWarning) + return super(_DeprecatedBool, self).__nonzero__() def _python_build(): return _DeprecatedBool(_sysconfig._PYTHON_BUILD) python_build = _python_build() -_DEPRECATION_MSG = ("distutils.sysconfig.%s is deprecated. " - "Use the APIs provided by the sysconfig module instead") - def get_python_version(): """This function is deprecated. From python-checkins at python.org Mon Nov 30 22:13:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 21:13:52 -0000 Subject: [Python-checkins] r76602 - python/trunk/Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Mon Nov 30 22:13:52 2009 New Revision: 76602 Log: Handle step values other than one. Modified: python/trunk/Modules/itertoolsmodule.c Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Mon Nov 30 22:13:52 2009 @@ -3379,7 +3379,7 @@ count_reduce(countobject *lz) { if (lz->cnt == PY_SSIZE_T_MAX) - return Py_BuildValue("O(O)", Py_TYPE(lz), lz->long_cnt); + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); } @@ -3388,6 +3388,7 @@ static PyMethodDef count_methods[] = { {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, count_reduce_doc}, + {NULL, NULL} /* sentinel */ }; PyDoc_STRVAR(count_doc, From python-checkins at python.org Mon Nov 30 22:14:26 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 21:14:26 -0000 Subject: [Python-checkins] r76603 - python/trunk/PC/VS8.0/pythoncore.vcproj Message-ID: Author: raymond.hettinger Date: Mon Nov 30 22:14:25 2009 New Revision: 76603 Log: Update project file for new file: dtoa.c Modified: python/trunk/PC/VS8.0/pythoncore.vcproj Modified: python/trunk/PC/VS8.0/pythoncore.vcproj ============================================================================== --- python/trunk/PC/VS8.0/pythoncore.vcproj (original) +++ python/trunk/PC/VS8.0/pythoncore.vcproj Mon Nov 30 22:14:25 2009 @@ -1687,6 +1687,10 @@ > + + From python-checkins at python.org Mon Nov 30 22:33:32 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 21:33:32 -0000 Subject: [Python-checkins] r76604 - python/branches/release26-maint/Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Mon Nov 30 22:33:31 2009 New Revision: 76604 Log: Add sentinel Modified: python/branches/release26-maint/Modules/itertoolsmodule.c Modified: python/branches/release26-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release26-maint/Modules/itertoolsmodule.c Mon Nov 30 22:33:31 2009 @@ -2919,6 +2919,7 @@ static PyMethodDef count_methods[] = { {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, count_reduce_doc}, + {NULL, NULL} /* sentinel */ }; PyDoc_STRVAR(count_doc, From python-checkins at python.org Mon Nov 30 22:51:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 30 Nov 2009 21:51:30 -0000 Subject: [Python-checkins] r76605 - in python/trunk/PC: VC6/pythoncore.dsp VS7.1/pythoncore.vcproj VS8.0/pythoncore.vcproj Message-ID: Author: mark.dickinson Date: Mon Nov 30 22:51:30 2009 New Revision: 76605 Log: Add dtoa.c and dtoa.h to the relevant project files. Modified: python/trunk/PC/VC6/pythoncore.dsp python/trunk/PC/VS7.1/pythoncore.vcproj python/trunk/PC/VS8.0/pythoncore.vcproj Modified: python/trunk/PC/VC6/pythoncore.dsp ============================================================================== --- python/trunk/PC/VC6/pythoncore.dsp (original) +++ python/trunk/PC/VC6/pythoncore.dsp Mon Nov 30 22:51:30 2009 @@ -329,6 +329,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Python\dtoa.c +# End Source File +# Begin Source File + SOURCE=..\..\Python\dynload_win.c # End Source File # Begin Source File Modified: python/trunk/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/trunk/PC/VS7.1/pythoncore.vcproj (original) +++ python/trunk/PC/VS7.1/pythoncore.vcproj Mon Nov 30 22:51:30 2009 @@ -512,6 +512,9 @@ RelativePath="..\..\PC\dl_nt.c"> + + + + From python-checkins at python.org Mon Nov 30 22:53:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 30 Nov 2009 21:53:10 -0000 Subject: [Python-checkins] r76606 - python/branches/release26-maint Message-ID: Author: mark.dickinson Date: Mon Nov 30 22:53:09 2009 New Revision: 76606 Log: Blocked revisions 76603,76605 via svnmerge ........ r76603 | raymond.hettinger | 2009-11-30 21:14:25 +0000 (Mon, 30 Nov 2009) | 1 line Update project file for new file: dtoa.c ........ r76605 | mark.dickinson | 2009-11-30 21:51:30 +0000 (Mon, 30 Nov 2009) | 2 lines Add dtoa.c and dtoa.h to the relevant project files. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Nov 30 22:53:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 30 Nov 2009 21:53:53 -0000 Subject: [Python-checkins] r76607 - python/branches/py3k Message-ID: Author: mark.dickinson Date: Mon Nov 30 22:53:52 2009 New Revision: 76607 Log: Blocked revisions 76603,76605 via svnmerge ........ r76603 | raymond.hettinger | 2009-11-30 21:14:25 +0000 (Mon, 30 Nov 2009) | 1 line Update project file for new file: dtoa.c ........ r76605 | mark.dickinson | 2009-11-30 21:51:30 +0000 (Mon, 30 Nov 2009) | 2 lines Add dtoa.c and dtoa.h to the relevant project files. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Nov 30 22:55:17 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 21:55:17 -0000 Subject: [Python-checkins] r76608 - in python/branches/release31-maint: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Mon Nov 30 22:55:17 2009 New Revision: 76608 Log: Issue #7410: deepcopy of itertools.count was resetting the count. Modified: python/branches/release31-maint/Lib/test/test_itertools.py python/branches/release31-maint/Misc/NEWS python/branches/release31-maint/Modules/itertoolsmodule.c Modified: python/branches/release31-maint/Lib/test/test_itertools.py ============================================================================== --- python/branches/release31-maint/Lib/test/test_itertools.py (original) +++ python/branches/release31-maint/Lib/test/test_itertools.py Mon Nov 30 22:55:17 2009 @@ -7,6 +7,8 @@ import sys import operator import random +import copy +import pickle from functools import reduce maxsize = support.MAX_Py_ssize_t minsize = -maxsize-1 @@ -352,6 +354,13 @@ r2 = 'count(%r)'.__mod__(i).replace('L', '') self.assertEqual(r1, r2) + # check copy, deepcopy, pickle + for value in -3, 3, maxsize-5, maxsize+5: + c = count(value) + self.assertEqual(next(copy.copy(c)), value) + self.assertEqual(next(copy.deepcopy(c)), value) + self.assertEqual(next(pickle.loads(pickle.dumps(c))), value) + def test_count_with_stride(self): self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)]) self.assertEqual(lzip('abc',count(start=2,step=3)), Modified: python/branches/release31-maint/Misc/NEWS ============================================================================== --- python/branches/release31-maint/Misc/NEWS (original) +++ python/branches/release31-maint/Misc/NEWS Mon Nov 30 22:55:17 2009 @@ -52,6 +52,8 @@ Library ------- +- Issue #7410: deepcopy of itertools.count was resetting the count. + - Issue #4486: When an exception has an explicit cause, do not print its implicit context too. This affects the `traceback` module as well as built-in exception printing. Modified: python/branches/release31-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release31-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release31-maint/Modules/itertoolsmodule.c Mon Nov 30 22:55:17 2009 @@ -3049,6 +3049,22 @@ lz->long_cnt, lz->long_step); } +static PyObject * +count_reduce(countobject *lz) +{ + if (lz->cnt == PY_SSIZE_T_MAX) + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); + return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); +} + +PyDoc_STRVAR(count_reduce_doc, "Return state information for pickling."); + +static PyMethodDef count_methods[] = { + {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, + count_reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + PyDoc_STRVAR(count_doc, "count(start=0, step=1]) --> count object\n\ \n\ @@ -3090,7 +3106,7 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ - 0, /* tp_methods */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ From dickinsm at gmail.com Mon Nov 30 22:56:00 2009 From: dickinsm at gmail.com (Mark Dickinson) Date: Mon, 30 Nov 2009 21:56:00 +0000 Subject: [Python-checkins] r76603 - python/trunk/PC/VS8.0/pythoncore.vcproj In-Reply-To: <4b143cb2.1a67f10a.550c.155bSMTPIN_ADDED@mx.google.com> References: <4b143cb2.1a67f10a.550c.155bSMTPIN_ADDED@mx.google.com> Message-ID: <5c6f2a5d0911301356v7e51bd6cs67fc387315658300@mail.gmail.com> On Mon, Nov 30, 2009 at 9:44 PM, raymond.hettinger wrote: > Author: raymond.hettinger > Date: Mon Nov 30 22:14:25 2009 > New Revision: 76603 > > Log: > Update project file for new file: dtoa.c Thanks; I missed that. I've now added dtoa.h as well, and put dtoa.c in the appropriate place in the PC/VS7.1 and PC/VC6 directories. From python-checkins at python.org Mon Nov 30 23:02:31 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 30 Nov 2009 22:02:31 -0000 Subject: [Python-checkins] r76609 - in python/branches/py3k: Lib/test/test_itertools.py Modules/itertoolsmodule.c Message-ID: Author: raymond.hettinger Date: Mon Nov 30 23:02:31 2009 New Revision: 76609 Log: Issue 7410: deepcopy of itertools.count() reset the count. Modified: python/branches/py3k/Lib/test/test_itertools.py python/branches/py3k/Modules/itertoolsmodule.c Modified: python/branches/py3k/Lib/test/test_itertools.py ============================================================================== --- python/branches/py3k/Lib/test/test_itertools.py (original) +++ python/branches/py3k/Lib/test/test_itertools.py Mon Nov 30 23:02:31 2009 @@ -7,6 +7,8 @@ import sys import operator import random +import copy +import pickle from functools import reduce maxsize = support.MAX_Py_ssize_t minsize = -maxsize-1 @@ -352,6 +354,13 @@ r2 = 'count(%r)'.__mod__(i).replace('L', '') self.assertEqual(r1, r2) + # check copy, deepcopy, pickle + for value in -3, 3, maxsize-5, maxsize+5: + c = count(value) + self.assertEqual(next(copy.copy(c)), value) + self.assertEqual(next(copy.deepcopy(c)), value) + self.assertEqual(next(pickle.loads(pickle.dumps(c))), value) + def test_count_with_stride(self): self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)]) self.assertEqual(lzip('abc',count(start=2,step=3)), Modified: python/branches/py3k/Modules/itertoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/itertoolsmodule.c (original) +++ python/branches/py3k/Modules/itertoolsmodule.c Mon Nov 30 23:02:31 2009 @@ -3049,6 +3049,22 @@ lz->long_cnt, lz->long_step); } +static PyObject * +count_reduce(countobject *lz) +{ + if (lz->cnt == PY_SSIZE_T_MAX) + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); + return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); +} + +PyDoc_STRVAR(count_reduce_doc, "Return state information for pickling."); + +static PyMethodDef count_methods[] = { + {"__reduce__", (PyCFunction)count_reduce, METH_NOARGS, + count_reduce_doc}, + {NULL, NULL} /* sentinel */ +}; + PyDoc_STRVAR(count_doc, "count(start=0, step=1]) --> count object\n\ \n\ @@ -3090,7 +3106,7 @@ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ - 0, /* tp_methods */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ From eric at trueblade.com Tue Nov 3 15:48:27 2009 From: eric at trueblade.com (Eric Smith) Date: Tue, 03 Nov 2009 14:48:27 -0000 Subject: [Python-checkins] r76078 - python/branches/release31-maint/Doc/library/datetime.rst In-Reply-To: <20091103024511.8089D181869D@tok.trueblade.com> References: <20091103024511.8089D181869D@tok.trueblade.com> Message-ID: <4AF04281.7020501@trueblade.com> It would be better if you could use svnmerge when you make the same revision in multiple branches. Thanks. Eric. skip.montanaro wrote: > Author: skip.montanaro > Date: Tue Nov 3 03:44:54 2009 > New Revision: 76078 > > Log: > typo (space-o?) > > Modified: > python/branches/release31-maint/Doc/library/datetime.rst > > Modified: python/branches/release31-maint/Doc/library/datetime.rst > ============================================================================== > --- python/branches/release31-maint/Doc/library/datetime.rst (original) > +++ python/branches/release31-maint/Doc/library/datetime.rst Tue Nov 3 03:44:54 2009 > @@ -469,7 +469,7 @@ > Return a 3-tuple, (ISO year, ISO week number, ISO weekday). > > The ISO calendar is a widely used variant of the Gregorian calendar. See > - http://www.phys.uu.nl/ vgent/calendar/isocalendar.htm for a good explanation. > + http://www.phys.uu.nl/vgent/calendar/isocalendar.htm for a good explanation. > > The ISO year consists of 52 or 53 full weeks, and where a week starts on a > Monday and ends on a Sunday. The first week of an ISO year is the first > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins >