From fabefc3c5b9e174e4eef2cb351a6ed8c81d721b0 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 21 Jun 2014 11:57:36 -0700 Subject: Issue 21635: Fix caching in difflib.SequenceMatcher.get_matching_blocks(). --- Lib/difflib.py | 4 ++-- Lib/test/test_difflib.py | 9 +++++++++ Misc/NEWS | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Lib/difflib.py b/Lib/difflib.py index 38dfef4..7eb42a9 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -511,8 +511,8 @@ class SequenceMatcher: non_adjacent.append((i1, j1, k1)) non_adjacent.append( (la, lb, 0) ) - self.matching_blocks = non_adjacent - return map(Match._make, self.matching_blocks) + self.matching_blocks = list(map(Match._make, non_adjacent)) + return self.matching_blocks def get_opcodes(self): """Return list of 5-tuples describing how to turn a into b. diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py index 325449a..0ba8f0e 100644 --- a/Lib/test/test_difflib.py +++ b/Lib/test/test_difflib.py @@ -76,6 +76,15 @@ class TestSFbugs(unittest.TestCase): diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, next, diff_gen) + def test_matching_blocks_cache(self): + # Issue #21635 + s = difflib.SequenceMatcher(None, "abxcd", "abcd") + first = s.get_matching_blocks() + second = s.get_matching_blocks() + self.assertEqual(second[0].size, 2) + self.assertEqual(second[1].size, 2) + self.assertEqual(second[2].size, 0) + 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"])) diff --git a/Misc/NEWS b/Misc/NEWS index b8e7219..a94d073 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -29,6 +29,10 @@ Library - Issue #21491: socketserver: Fix a race condition in child processes reaping. +- Issue #21635: The difflib SequenceMatcher.get_matching_blocks() method + cache didn't match the actual result. The former was a list of tuples + and the latter was a list of named tuples. + - Issue #21722: The distutils "upload" command now exits with a non-zero return code when uploading fails. Patch by Martin Dengler. -- cgit v0.12 From bb91c1d0198b25dbaced789d543ae785378654ed Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 21 Jun 2014 12:08:22 -0700 Subject: Issue 21786: Clean-up test_pydoc taking taking advantage of diffing in unittest. --- Lib/test/test_pydoc.py | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 3bce66e..e5794c8 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -2,7 +2,6 @@ import os import sys import builtins import contextlib -import difflib import inspect import pydoc import keyword @@ -356,15 +355,6 @@ def get_pydoc_text(module): output = patt.sub('', output) return output.strip(), loc -def print_diffs(text1, text2): - "Prints unified diffs for two texts" - # XXX now obsolete, use unittest built-in support - lines1 = text1.splitlines(keepends=True) - lines2 = text2.splitlines(keepends=True) - diffs = difflib.unified_diff(lines1, lines2, n=0, fromfile='expected', - tofile='got') - print('\n' + ''.join(diffs)) - def get_html_title(text): # Bit of hack, but good enough for test purposes header, _, _ = text.partition("") @@ -414,9 +404,7 @@ class PydocDocTest(unittest.TestCase): expected_html = expected_html_pattern % ( (mod_url, mod_file, doc_loc) + expected_html_data_docstrings) - if result != expected_html: - print_diffs(expected_html, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(result, expected_html) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -429,9 +417,7 @@ class PydocDocTest(unittest.TestCase): (doc_loc,) + expected_text_data_docstrings + (inspect.getabsfile(pydoc_mod),)) - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) def test_text_enum_member_with_value_zero(self): # Test issue #20654 to ensure enum member with value 0 can be @@ -887,9 +873,7 @@ class PydocWithMetaClasses(unittest.TestCase): expected_text = expected_dynamicattribute_pattern % ( (__name__,) + expected_text_data_docstrings[:2]) result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -910,9 +894,7 @@ class PydocWithMetaClasses(unittest.TestCase): helper(Class) expected_text = expected_virtualattribute_pattern1 % __name__ result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -952,19 +934,13 @@ class PydocWithMetaClasses(unittest.TestCase): helper(Class1) expected_text1 = expected_virtualattribute_pattern2 % __name__ result1 = output.getvalue().strip() - if result1 != expected_text1: - print_diffs(expected_text1, result1) - fail1 = True + self.assertEqual(expected_text1, result1) output = StringIO() helper = pydoc.Helper(output=output) helper(Class2) expected_text2 = expected_virtualattribute_pattern3 % __name__ result2 = output.getvalue().strip() - if result2 != expected_text2: - print_diffs(expected_text2, result2) - fail2 = True - if fail1 or fail2: - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text2, result2) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -981,9 +957,7 @@ class PydocWithMetaClasses(unittest.TestCase): helper(C) expected_text = expected_missingattribute_pattern % __name__ result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) @reap_threads -- cgit v0.12 From f51531e2578452a47914108a44bc74c15431a5b0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 22 Jun 2014 01:18:54 -0400 Subject: Issue #21823: Catch turtle.Terminator exceptions in turtledemo. Add note to demohelp.txt about doing so. --- Lib/turtledemo/clock.py | 36 ++++++++++++++++++++---------------- Lib/turtledemo/demohelp.txt | 16 ++++++++++------ Lib/turtledemo/minimal_hanoi.py | 10 +++++++--- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Lib/turtledemo/clock.py b/Lib/turtledemo/clock.py index a0d157b..b7a2f36 100755 --- a/Lib/turtledemo/clock.py +++ b/Lib/turtledemo/clock.py @@ -11,6 +11,7 @@ and time ------------------------------------ """ from turtle import * +from turtle import Terminator # not in __all__ from datetime import datetime mode("logo") @@ -102,22 +103,25 @@ def tick(): sekunde = t.second + t.microsecond*0.000001 minute = t.minute + sekunde/60.0 stunde = t.hour + minute/60.0 - tracer(False) - writer.clear() - writer.home() - writer.forward(65) - writer.write(wochentag(t), - align="center", font=("Courier", 14, "bold")) - writer.back(150) - writer.write(datum(t), - align="center", font=("Courier", 14, "bold")) - writer.forward(85) - tracer(True) - second_hand.setheading(6*sekunde) - minute_hand.setheading(6*minute) - hour_hand.setheading(30*stunde) - tracer(True) - ontimer(tick, 100) + try: + tracer(False) # Terminator can occur here + writer.clear() + writer.home() + writer.forward(65) + writer.write(wochentag(t), + align="center", font=("Courier", 14, "bold")) + writer.back(150) + writer.write(datum(t), + align="center", font=("Courier", 14, "bold")) + writer.forward(85) + tracer(True) + second_hand.setheading(6*sekunde) # or here + minute_hand.setheading(6*minute) + hour_hand.setheading(30*stunde) + tracer(True) + ontimer(tick, 100) + except Terminator: + pass # turtledemo user pressed STOP def main(): tracer(False) diff --git a/Lib/turtledemo/demohelp.txt b/Lib/turtledemo/demohelp.txt index fe83bc7..96af26d 100644 --- a/Lib/turtledemo/demohelp.txt +++ b/Lib/turtledemo/demohelp.txt @@ -60,11 +60,15 @@ be executed by the viewer (see provided example scripts) main() may return a string which will be displayed in the Label below the source code window (when execution - has finished.) + has finished.) - !! For programs, which are EVENT DRIVEN, main must return - !! the string "EVENTLOOP". This informs the viewer, that the - !! script is still running and must be stopped by the user! + If the demo is EVENT DRIVEN, main must return the string + "EVENTLOOP". This informs the demo viewer that the script is + still running and must be stopped by the user! + + If an "EVENTLOOP" demo runs by itself, as with clock, which uses + ontimer, or minimal_hanoi, which loops by recursion, then the + code should catch the turtle.Terminator exception that will be + raised when the user presses the STOP button. (Paint is not such + a demo; it only acts in response to mouse clicks and movements.) - - diff --git a/Lib/turtledemo/minimal_hanoi.py b/Lib/turtledemo/minimal_hanoi.py index cfb78dc..5e9c27b 100755 --- a/Lib/turtledemo/minimal_hanoi.py +++ b/Lib/turtledemo/minimal_hanoi.py @@ -18,6 +18,7 @@ stretched to rectangles by shapesize() --------------------------------------- """ from turtle import * +from turtle import Terminator # not in __all__ class Disc(Turtle): def __init__(self, n): @@ -50,9 +51,12 @@ def hanoi(n, from_, with_, to_): def play(): onkey(None,"space") clear() - hanoi(6, t1, t2, t3) - write("press STOP button to exit", - align="center", font=("Courier", 16, "bold")) + try: + hanoi(6, t1, t2, t3) + write("press STOP button to exit", + align="center", font=("Courier", 16, "bold")) + except Terminator: + pass # turtledemo user pressed STOP def main(): global t1, t2, t3 -- cgit v0.12 From 6dec4eae536b3e55bf18b5804eb01f8110d4bafb Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 22 Jun 2014 01:21:51 -0700 Subject: Issue #21812: Trigger immediate transformation in turtle.shapetransform(). --- Lib/turtle.py | 2 +- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/turtle.py b/Lib/turtle.py index 599f645..3d1d3b0 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -2945,7 +2945,7 @@ class RawTurtle(TPen, TNavigator): self._stretchfactor = a11, a22 self._shearfactor = a12/a22 self._tilt = alfa - self._update() + self.pen(resizemode="user") def _polytrafo(self, poly): diff --git a/Misc/ACKS b/Misc/ACKS index c42b02b..9787d8e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -235,6 +235,7 @@ Ingrid Cheung Albert Chin-A-Young Adal Chiriliuc Matt Chisholm +Lita Cho Anders Chrigström Tom Christiansen Vadim Chugunov diff --git a/Misc/NEWS b/Misc/NEWS index a94d073..848eb86 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -29,6 +29,9 @@ Library - Issue #21491: socketserver: Fix a race condition in child processes reaping. +- Issue #21812: turtle.shapetransform did not tranform the turtle on the + first call. (Issue identified and fixed by Lita Cho.) + - Issue #21635: The difflib SequenceMatcher.get_matching_blocks() method cache didn't match the actual result. The former was a list of tuples and the latter was a list of named tuples. -- cgit v0.12