Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Checkins

cpython (merge 3.3 -> default): merge with 3.3

 

 

First page Previous page 1 2 Next page Last page  View All Python checkins RSS feed   Index | Next | Previous | View Threaded


python-checkins at python

Jul 27, 2013, 1:16 PM

Post #26 of 34 (28 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/852e824c7093
changeset: 84867:852e824c7093
parent: 84864:35c88c53cf64
parent: 84866:55dcf9e065be
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sat Jul 27 16:15:51 2013 -0400
summary:
Merge with 3.3

files:
Doc/library/unittest.rst | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)


diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst
--- a/Doc/library/unittest.rst
+++ b/Doc/library/unittest.rst
@@ -985,7 +985,7 @@
with self.assertWarns(SomeWarning):
do_something()

- When used as a context manager, :meth:`assertRaises` accepts the
+ When used as a context manager, :meth:`assertWarns` accepts the
additional keyword argument *msg*.

The context manager will store the caught warning object in its

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Jul 27, 2013, 9:01 PM

Post #27 of 34 (28 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/a6cac0aff498
changeset: 84879:a6cac0aff498
parent: 84874:66a3dc613627
parent: 84878:c3936a52f215
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sun Jul 28 00:00:47 2013 -0400
summary:
Merge with 3.3

files:
Lib/test/test_idle.py | 22 +++++++++++++++++-----
1 files changed, 17 insertions(+), 5 deletions(-)


diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py
--- a/Lib/test/test_idle.py
+++ b/Lib/test/test_idle.py
@@ -1,9 +1,23 @@
-# Skip test if _tkinter or _thread wasn't built or idlelib was deleted.
-from test.support import import_module
-import_module('tkinter')
+import unittest
+from test import support
+from test.support import import_module, use_resources
+
+# Skip test if _thread or _tkinter wasn't built or idlelib was deleted.
import_module('threading') # imported by PyShell, imports _thread
+tk = import_module('tkinter') # imports _tkinter
idletest = import_module('idlelib.idle_test')

+# If buildbot improperly sets gui resource (#18365, #18441), remove it
+# so requires('gui') tests are skipped while non-gui tests still run.
+# If there is a problem with Macs, see #18441, msg 193805
+if use_resources and 'gui' in use_resources:
+ try:
+ root = tk.Tk()
+ root.destroy()
+ except tk.TclError:
+ while 'gui' in use_resources:
+ use_resources.remove('gui')
+
# Without test_main present, regrtest.runtest_inner (line1219) calls
# unittest.TestLoader().loadTestsFromModule(this_module) which calls
# load_tests() if it finds it. (Unittest.main does the same.)
@@ -13,7 +27,5 @@
# Until unittest supports resources, we emulate regrtest's -ugui
# so loaded tests run the same as if textually present here.
# If any Idle test ever needs another resource, add it to the list.
- from test import support
support.use_resources = ['gui'] # use_resources is initially None
- import unittest
unittest.main(verbosity=2, exit=False)

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Jul 28, 2013, 1:26 PM

Post #28 of 34 (28 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/f8c0062aa12c
changeset: 84890:f8c0062aa12c
parent: 84888:b20a10c97e08
parent: 84889:c57b2a344097
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sun Jul 28 16:25:52 2013 -0400
summary:
Merge with 3.3

files:
Lib/idlelib/idle_test/test_text.py | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)


diff --git a/Lib/idlelib/idle_test/test_text.py b/Lib/idlelib/idle_test/test_text.py
--- a/Lib/idlelib/idle_test/test_text.py
+++ b/Lib/idlelib/idle_test/test_text.py
@@ -216,10 +216,7 @@
requires('gui')
from tkinter import Tk, Text
cls.Text = Text
- try:
- cls.root = Tk()
- except TclError as msg:
- raise unittest.SkipTest('TclError: %s' % msg)
+ cls.root = Tk()

@classmethod
def tearDownClass(cls):

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Jul 28, 2013, 1:41 PM

Post #29 of 34 (28 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/4d08db5edbaa
changeset: 84892:4d08db5edbaa
parent: 84890:f8c0062aa12c
parent: 84891:70a4287a25b4
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sun Jul 28 16:40:07 2013 -0400
summary:
Merge with 3.3

files:
Lib/idlelib/idle_test/README.txt | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)


diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt
--- a/Lib/idlelib/idle_test/README.txt
+++ b/Lib/idlelib/idle_test/README.txt
@@ -40,13 +40,20 @@
idle class. For the benefit of buildbot machines that do not have a graphics
screen, gui tests must be 'guarded' by "requires('gui')" in a setUp
function or method. This will typically be setUpClass.
+
+All gui objects must be destroyed by the end of the test, perhaps in a tearDown
+function. Creating the Tk root directly in a setUp allows a reference to be saved
+so it can be properly destroyed in the corresponding tearDown.
---
@classmethod
def setUpClass(cls):
requires('gui')
+ cls.root = tk.Tk()
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.root.destroy()
---
-All gui objects must be destroyed by the end of the test, perhaps in a tearDown
-function.

Support.requires('gui') returns true if it is either called in a main module
(which never happens on buildbots) or if use_resources contains 'gui'.
@@ -56,8 +63,9 @@

Since non-gui tests always run, but gui tests only sometimes, tests of non-gui
operations should best avoid needing a gui. Methods that make incidental use of
-tkinter variables and messageboxes can do this by using the mock classes in
-idle_test/mock_tk.py.
+tkinter (tk) variables and messageboxes can do this by using the mock classes in
+idle_test/mock_tk.py. There is also a mock text that will handle some uses of the
+tk Text widget.


3. Running Tests

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Jul 29, 2013, 10:37 PM

Post #30 of 34 (27 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/83b404da05e9
changeset: 84901:83b404da05e9
parent: 84899:206685a4b19c
parent: 84900:aa13693e3356
user: Terry Jan Reedy <tjreedy [at] udel>
date: Tue Jul 30 01:37:28 2013 -0400
summary:
Merge with 3.3

files:
Lib/idlelib/idle_test/test_calltips.py | 2 +-
Lib/idlelib/idle_test/test_config_name.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)


diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py
--- a/Lib/idlelib/idle_test/test_calltips.py
+++ b/Lib/idlelib/idle_test/test_calltips.py
@@ -1,7 +1,7 @@
import unittest
import idlelib.CallTips as ct

-class Test_get_entity(unittest.TestCase):
+class Get_entityTest(unittest.TestCase):
def test_bad_entity(self):
self.assertIsNone(ct.get_entity('1/0'))
def test_good_entity(self):
diff --git a/Lib/idlelib/idle_test/test_config_name.py b/Lib/idlelib/idle_test/test_config_name.py
--- a/Lib/idlelib/idle_test/test_config_name.py
+++ b/Lib/idlelib/idle_test/test_config_name.py
@@ -22,7 +22,7 @@
orig_mbox = name_dialog_module.tkMessageBox
showerror = Mbox.showerror

-class TestConfigName(unittest.TestCase):
+class ConfigNameTest(unittest.TestCase):
dialog = Dummy_name_dialog()

@classmethod

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Jul 30, 2013, 7:31 PM

Post #31 of 34 (27 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/acfb863b0937
changeset: 84927:acfb863b0937
parent: 84925:5cea8bc7bc7f
parent: 84926:366beee880aa
user: Terry Jan Reedy <tjreedy [at] udel>
date: Tue Jul 30 22:31:30 2013 -0400
summary:
Merge with 3.3

files:
Doc/library/unittest.rst | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)


diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst
--- a/Doc/library/unittest.rst
+++ b/Doc/library/unittest.rst
@@ -974,12 +974,12 @@
Test that a warning is triggered when *callable* is called with any
positional or keyword arguments that are also passed to
:meth:`assertWarns`. The test passes if *warning* is triggered and
- fails if it isn't. Also, any unexpected exception is an error.
+ fails if it isn't. Any exception is an error.
To catch any of a group of warnings, a tuple containing the warning
classes may be passed as *warnings*.

If only the *warning* and possibly the *msg* arguments are given,
- returns a context manager so that the code under test can be written
+ return a context manager so that the code under test can be written
inline rather than as a function::

with self.assertWarns(SomeWarning):
@@ -992,7 +992,7 @@
:attr:`warning` attribute, and the source line which triggered the
warnings in the :attr:`filename` and :attr:`lineno` attributes.
This can be useful if the intention is to perform additional checks
- on the exception raised::
+ on the warning caught::

with self.assertWarns(SomeWarning) as cm:
do_something()

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Aug 4, 2013, 12:40 PM

Post #32 of 34 (6 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/af4105810309
changeset: 85031:af4105810309
parent: 85029:168768bf428d
parent: 85030:e450e85e2075
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sun Aug 04 15:39:32 2013 -0400
summary:
Merge with 3.3

files:
Lib/idlelib/EditorWindow.py | 7 ++-----
Lib/idlelib/IOBinding.py | 15 ++++++---------
Lib/idlelib/ScriptBinding.py | 5 ++---
3 files changed, 10 insertions(+), 17 deletions(-)


diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -882,12 +882,9 @@
"Load and update the recent files list and menus"
rf_list = []
if os.path.exists(self.recent_files_path):
- rf_list_file = open(self.recent_files_path,'r',
- encoding='utf_8', errors='replace')
- try:
+ with open(self.recent_files_path, 'r',
+ encoding='utf_8', errors='replace') as rf_list_file:
rf_list = rf_list_file.readlines()
- finally:
- rf_list_file.close()
if new_file:
new_file = os.path.abspath(new_file) + '\n'
if new_file in rf_list:
diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py
--- a/Lib/idlelib/IOBinding.py
+++ b/Lib/idlelib/IOBinding.py
@@ -208,11 +208,10 @@
try:
# open the file in binary mode so that we can handle
# end-of-line convention ourselves.
- f = open(filename,'rb')
- two_lines = f.readline() + f.readline()
- f.seek(0)
- bytes = f.read()
- f.close()
+ with open(filename, 'rb') as f:
+ two_lines = f.readline() + f.readline()
+ f.seek(0)
+ bytes = f.read()
except OSError as msg:
tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
return False
@@ -373,10 +372,8 @@
text = text.replace("\n", self.eol_convention)
chars = self.encode(text)
try:
- f = open(filename, "wb")
- f.write(chars)
- f.flush()
- f.close()
+ with open(filename, "wb") as f:
+ f.write(chars)
return True
except OSError as msg:
tkMessageBox.showerror("I/O Error", str(msg),
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -87,9 +87,8 @@
self.shell = shell = self.flist.open_shell()
saved_stream = shell.get_warning_stream()
shell.set_warning_stream(shell.stderr)
- f = open(filename, 'rb')
- source = f.read()
- f.close()
+ with open(filename, 'rb') as f:
+ source = f.read()
if b'\r' in source:
source = source.replace(b'\r\n', b'\n')
source = source.replace(b'\r', b'\n')

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Aug 10, 2013, 1:57 PM

Post #33 of 34 (2 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/b4a30d329f49
changeset: 85107:b4a30d329f49
parent: 85104:5d417257748e
parent: 85106:bfdb687ca485
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sat Aug 10 16:57:02 2013 -0400
summary:
Merge with 3.3

files:
Lib/idlelib/FormatParagraph.py | 134 ++-
Lib/idlelib/idle_test/test_formatparagraph.py | 374 ++++++++++
Misc/NEWS | 3 +
3 files changed, 464 insertions(+), 47 deletions(-)


diff --git a/Lib/idlelib/FormatParagraph.py b/Lib/idlelib/FormatParagraph.py
--- a/Lib/idlelib/FormatParagraph.py
+++ b/Lib/idlelib/FormatParagraph.py
@@ -1,18 +1,19 @@
-# Extension to format a paragraph
+"""Extension to format a paragraph or selection to a max width.

-# Does basic, standard text formatting, and also understands Python
-# comment blocks. Thus, for editing Python source code, this
-# extension is really only suitable for reformatting these comment
-# blocks or triple-quoted strings.
+Does basic, standard text formatting, and also understands Python
+comment blocks. Thus, for editing Python source code, this
+extension is really only suitable for reformatting these comment
+blocks or triple-quoted strings.

-# Known problems with comment reformatting:
-# * If there is a selection marked, and the first line of the
-# selection is not complete, the block will probably not be detected
-# as comments, and will have the normal "text formatting" rules
-# applied.
-# * If a comment block has leading whitespace that mixes tabs and
-# spaces, they will not be considered part of the same block.
-# * Fancy comments, like this bulleted list, arent handled :-)
+Known problems with comment reformatting:
+* If there is a selection marked, and the first line of the
+ selection is not complete, the block will probably not be detected
+ as comments, and will have the normal "text formatting" rules
+ applied.
+* If a comment block has leading whitespace that mixes tabs and
+ spaces, they will not be considered part of the same block.
+* Fancy comments, like this bulleted list, aren't handled :-)
+"""

import re
from idlelib.configHandler import idleConf
@@ -32,42 +33,31 @@
self.editwin = None

def format_paragraph_event(self, event):
- maxformatwidth = int(idleConf.GetOption('main', 'FormatParagraph',
- 'paragraph', type='int'))
+ """Formats paragraph to a max width specified in idleConf.
+
+ If text is selected, format_paragraph_event will start breaking lines
+ at the max width, starting from the beginning selection.
+
+ If no text is selected, format_paragraph_event uses the current
+ cursor location to determine the paragraph (lines of text surrounded
+ by blank lines) and formats it.
+ """
+ maxformatwidth = idleConf.GetOption(
+ 'main', 'FormatParagraph', 'paragraph', type='int')
text = self.editwin.text
first, last = self.editwin.get_selection_indices()
if first and last:
data = text.get(first, last)
- comment_header = ''
+ comment_header = get_comment_header(data)
else:
first, last, comment_header, data = \
find_paragraph(text, text.index("insert"))
if comment_header:
- # Reformat the comment lines - convert to text sans header.
- lines = data.split("\n")
- lines = map(lambda st, l=len(comment_header): st[l:], lines)
- data = "\n".join(lines)
- # Reformat to maxformatwidth chars or a 20 char width,
- # whichever is greater.
- format_width = max(maxformatwidth - len(comment_header), 20)
- newdata = reformat_paragraph(data, format_width)
- # re-split and re-insert the comment header.
- newdata = newdata.split("\n")
- # If the block ends in a \n, we dont want the comment
- # prefix inserted after it. (Im not sure it makes sense to
- # reformat a comment block that isnt made of complete
- # lines, but whatever!) Can't think of a clean solution,
- # so we hack away
- block_suffix = ""
- if not newdata[-1]:
- block_suffix = "\n"
- newdata = newdata[:-1]
- builder = lambda item, prefix=comment_header: prefix+item
- newdata = '\n'.join(map(builder, newdata)) + block_suffix
+ newdata = reformat_comment(data, maxformatwidth, comment_header)
else:
- # Just a normal text format
newdata = reformat_paragraph(data, maxformatwidth)
text.tag_remove("sel", "1.0", "end")
+
if newdata != data:
text.mark_set("insert", first)
text.undo_block_start()
@@ -80,31 +70,44 @@
return "break"

def find_paragraph(text, mark):
+ """Returns the start/stop indices enclosing the paragraph that mark is in.
+
+ Also returns the comment format string, if any, and paragraph of text
+ between the start/stop indices.
+ """
lineno, col = map(int, mark.split("."))
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+ line = text.get("%d.0" % lineno, "%d.end" % lineno)
+
+ # Look for start of next paragraph if the index passed in is a blank line
while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line):
lineno = lineno + 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+ line = text.get("%d.0" % lineno, "%d.end" % lineno)
first_lineno = lineno
comment_header = get_comment_header(line)
comment_header_len = len(comment_header)
+
+ # Once start line found, search for end of paragraph (a blank line)
while get_comment_header(line)==comment_header and \
not is_all_white(line[comment_header_len:]):
lineno = lineno + 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+ line = text.get("%d.0" % lineno, "%d.end" % lineno)
last = "%d.0" % lineno
- # Search back to beginning of paragraph
+
+ # Search back to beginning of paragraph (first blank line before)
lineno = first_lineno - 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+ line = text.get("%d.0" % lineno, "%d.end" % lineno)
while lineno > 0 and \
get_comment_header(line)==comment_header and \
not is_all_white(line[comment_header_len:]):
lineno = lineno - 1
- line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
+ line = text.get("%d.0" % lineno, "%d.end" % lineno)
first = "%d.0" % (lineno+1)
+
return first, last, comment_header, text.get(first, last)

+# This should perhaps be replaced with textwrap.wrap
def reformat_paragraph(data, limit):
+ """Return data reformatted to specified width (limit)."""
lines = data.split("\n")
i = 0
n = len(lines)
@@ -127,7 +130,7 @@
if not word:
continue # Can happen when line ends in whitespace
if len((partial + word).expandtabs()) > limit and \
- partial != indent1:
+ partial != indent1:
new.append(partial.rstrip())
partial = indent2
partial = partial + word + " "
@@ -139,13 +142,50 @@
new.extend(lines[i:])
return "\n".join(new)

+def reformat_comment(data, limit, comment_header):
+ """Return data reformatted to specified width with comment header."""
+
+ # Remove header from the comment lines
+ lc = len(comment_header)
+ data = "\n".join(line[lc:] for line in data.split("\n"))
+ # Reformat to maxformatwidth chars or a 20 char width,
+ # whichever is greater.
+ format_width = max(limit - len(comment_header), 20)
+ newdata = reformat_paragraph(data, format_width)
+ # re-split and re-insert the comment header.
+ newdata = newdata.split("\n")
+ # If the block ends in a \n, we dont want the comment prefix
+ # inserted after it. (Im not sure it makes sense to reformat a
+ # comment block that is not made of complete lines, but whatever!)
+ # Can't think of a clean solution, so we hack away
+ block_suffix = ""
+ if not newdata[-1]:
+ block_suffix = "\n"
+ newdata = newdata[:-1]
+ return '\n'.join(comment_header+line for line in newdata) + block_suffix
+
def is_all_white(line):
+ """Return True if line is empty or all whitespace."""
+
return re.match(r"^\s*$", line) is not None

def get_indent(line):
- return re.match(r"^(\s*)", line).group()
+ """Return the initial space or tab indent of line."""
+ return re.match(r"^([ \t]*)", line).group()

def get_comment_header(line):
- m = re.match(r"^(\s*#*)", line)
+ """Return string with leading whitespace and '#' from line or ''.
+
+ A null return indicates that the line is not a comment line. A non-
+ null return, such as ' #', will be used to find the other lines of
+ a comment block with the same indent.
+ """
+ m = re.match(r"^([ \t]*#*)", line)
if m is None: return ""
return m.group(1)
+
+if __name__ == "__main__":
+ from test import support; support.use_resources = ['gui']
+ import unittest
+ unittest.main('idlelib.idle_test.test_formatparagraph',
+ verbosity=2, exit=False)
diff --git a/Lib/idlelib/idle_test/test_formatparagraph.py b/Lib/idlelib/idle_test/test_formatparagraph.py
new file mode 100644
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_formatparagraph.py
@@ -0,0 +1,374 @@
+# Test the functions and main class method of FormatParagraph.py
+import unittest
+from idlelib import FormatParagraph as fp
+from idlelib.EditorWindow import EditorWindow
+from tkinter import Tk, Text, TclError
+from test.support import requires
+
+
+class Is_Get_Test(unittest.TestCase):
+ """Test the is_ and get_ functions"""
+ test_comment = '# This is a comment'
+ test_nocomment = 'This is not a comment'
+ trailingws_comment = '# This is a comment '
+ leadingws_comment = ' # This is a comment'
+ leadingws_nocomment = ' This is not a comment'
+
+ def test_is_all_white(self):
+ self.assertTrue(fp.is_all_white(''))
+ self.assertTrue(fp.is_all_white('\t\n\r\f\v'))
+ self.assertFalse(fp.is_all_white(self.test_comment))
+
+ def test_get_indent(self):
+ Equal = self.assertEqual
+ Equal(fp.get_indent(self.test_comment), '')
+ Equal(fp.get_indent(self.trailingws_comment), '')
+ Equal(fp.get_indent(self.leadingws_comment), ' ')
+ Equal(fp.get_indent(self.leadingws_nocomment), ' ')
+
+ def test_get_comment_header(self):
+ Equal = self.assertEqual
+ # Test comment strings
+ Equal(fp.get_comment_header(self.test_comment), '#')
+ Equal(fp.get_comment_header(self.trailingws_comment), '#')
+ Equal(fp.get_comment_header(self.leadingws_comment), ' #')
+ # Test non-comment strings
+ Equal(fp.get_comment_header(self.leadingws_nocomment), ' ')
+ Equal(fp.get_comment_header(self.test_nocomment), '')
+
+
+class FindTest(unittest.TestCase):
+ """Test the find_paragraph function in FormatParagraph.
+
+ Using the runcase() function, find_paragraph() is called with 'mark' set at
+ multiple indexes before and inside the test paragraph.
+
+ It appears that code with the same indentation as a quoted string is grouped
+ as part of the same paragraph, which is probably incorrect behavior.
+ """
+
+ @classmethod
+ def setUpClass(cls):
+ from idlelib.idle_test.mock_tk import Text
+ cls.text = Text()
+
+ def runcase(self, inserttext, stopline, expected):
+ # Check that find_paragraph returns the expected paragraph when
+ # the mark index is set to beginning, middle, end of each line
+ # up to but not including the stop line
+ text = self.text
+ text.insert('1.0', inserttext)
+ for line in range(1, stopline):
+ linelength = int(text.index("%d.end" % line).split('.')[1])
+ for col in (0, linelength//2, linelength):
+ tempindex = "%d.%d" % (line, col)
+ self.assertEqual(fp.find_paragraph(text, tempindex), expected)
+ text.delete('1.0', 'end')
+
+ def test_find_comment(self):
+ comment = (
+ "# Comment block with no blank lines before\n"
+ "# Comment line\n"
+ "\n")
+ self.runcase(comment, 3, ('1.0', '3.0', '#', comment[0:58]))
+
+ comment = (
+ "\n"
+ "# Comment block with whitespace line before and after\n"
+ "# Comment line\n"
+ "\n")
+ self.runcase(comment, 4, ('2.0', '4.0', '#', comment[1:70]))
+
+ comment = (
+ "\n"
+ " # Indented comment block with whitespace before and after\n"
+ " # Comment line\n"
+ "\n")
+ self.runcase(comment, 4, ('2.0', '4.0', ' #', comment[1:82]))
+
+ comment = (
+ "\n"
+ "# Single line comment\n"
+ "\n")
+ self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:23]))
+
+ comment = (
+ "\n"
+ " # Single line comment with leading whitespace\n"
+ "\n")
+ self.runcase(comment, 3, ('2.0', '3.0', ' #', comment[1:51]))
+
+ comment = (
+ "\n"
+ "# Comment immediately followed by code\n"
+ "x = 42\n"
+ "\n")
+ self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:40]))
+
+ comment = (
+ "\n"
+ " # Indented comment immediately followed by code\n"
+ "x = 42\n"
+ "\n")
+ self.runcase(comment, 3, ('2.0', '3.0', ' #', comment[1:53]))
+
+ comment = (
+ "\n"
+ "# Comment immediately followed by indented code\n"
+ " x = 42\n"
+ "\n")
+ self.runcase(comment, 3, ('2.0', '3.0', '#', comment[1:49]))
+
+ def test_find_paragraph(self):
+ teststring = (
+ '"""String with no blank lines before\n'
+ 'String line\n'
+ '"""\n'
+ '\n')
+ self.runcase(teststring, 4, ('1.0', '4.0', '', teststring[0:53]))
+
+ teststring = (
+ "\n"
+ '"""String with whitespace line before and after\n'
+ 'String line.\n'
+ '"""\n'
+ '\n')
+ self.runcase(teststring, 5, ('2.0', '5.0', '', teststring[1:66]))
+
+ teststring = (
+ '\n'
+ ' """Indented string with whitespace before and after\n'
+ ' Comment string.\n'
+ ' """\n'
+ '\n')
+ self.runcase(teststring, 5, ('2.0', '5.0', ' ', teststring[1:85]))
+
+ teststring = (
+ '\n'
+ '"""Single line string."""\n'
+ '\n')
+ self.runcase(teststring, 3, ('2.0', '3.0', '', teststring[1:27]))
+
+ teststring = (
+ '\n'
+ ' """Single line string with leading whitespace."""\n'
+ '\n')
+ self.runcase(teststring, 3, ('2.0', '3.0', ' ', teststring[1:55]))
+
+
+class ReformatFunctionTest(unittest.TestCase):
+ """Test the reformat_paragraph function without the editor window."""
+
+ def test_reformat_paragrah(self):
+ Equal = self.assertEqual
+ reform = fp.reformat_paragraph
+ hw = "O hello world"
+ Equal(reform(' ', 1), ' ')
+ Equal(reform("Hello world", 20), "Hello world")
+
+ # Test without leading newline
+ Equal(reform(hw, 1), "O\nhello\nworld")
+ Equal(reform(hw, 6), "O\nhello\nworld")
+ Equal(reform(hw, 7), "O hello\nworld")
+ Equal(reform(hw, 12), "O hello\nworld")
+ Equal(reform(hw, 13), "O hello world")
+
+ # Test with leading newline
+ hw = "\nO hello world"
+ Equal(reform(hw, 1), "\nO\nhello\nworld")
+ Equal(reform(hw, 6), "\nO\nhello\nworld")
+ Equal(reform(hw, 7), "\nO hello\nworld")
+ Equal(reform(hw, 12), "\nO hello\nworld")
+ Equal(reform(hw, 13), "\nO hello world")
+
+
+class ReformatCommentTest(unittest.TestCase):
+ """Test the reformat_comment function without the editor window."""
+
+ def test_reformat_comment(self):
+ Equal = self.assertEqual
+
+ # reformat_comment formats to a minimum of 20 characters
+ test_string = (
+ " \"\"\"this is a test of a reformat for a triple quoted string"
+ " will it reformat to less than 70 characters for me?\"\"\"")
+ result = fp.reformat_comment(test_string, 70, " ")
+ expected = (
+ " \"\"\"this is a test of a reformat for a triple quoted string will it\n"
+ " reformat to less than 70 characters for me?\"\"\"")
+ Equal(result, expected)
+
+ test_comment = (
+ "# this is a test of a reformat for a triple quoted string will "
+ "it reformat to less than 70 characters for me?")
+ result = fp.reformat_comment(test_comment, 70, "#")
+ expected = (
+ "# this is a test of a reformat for a triple quoted string will it\n"
+ "# reformat to less than 70 characters for me?")
+ Equal(result, expected)
+
+
+class FormatClassTest(unittest.TestCase):
+ def test_init_close(self):
+ instance = fp.FormatParagraph('editor')
+ self.assertEqual(instance.editwin, 'editor')
+ instance.close()
+ self.assertEqual(instance.editwin, None)
+
+
+# For testing format_paragraph_event, Initialize FormatParagraph with
+# a mock Editor with .text and .get_selection_indices. The text must
+# be a Text wrapper that adds two methods
+
+# A real EditorWindow creates unneeded, time-consuming baggage and
+# sometimes emits shutdown warnings like this:
+# "warning: callback failed in WindowList <class '_tkinter.TclError'>
+# : invalid command name ".55131368.windows".
+# Calling EditorWindow._close in tearDownClass prevents this but causes
+# other problems (windows left open).
+
+class TextWrapper:
+ def __init__(self, master):
+ self.text = Text(master=master)
+ def __getattr__(self, name):
+ return getattr(self.text, name)
+ def undo_block_start(self): pass
+ def undo_block_stop(self): pass
+
+class Editor:
+ def __init__(self, root):
+ self.text = TextWrapper(root)
+ get_selection_indices = EditorWindow. get_selection_indices
+
+class FormatEventTest(unittest.TestCase):
+ """Test the formatting of text inside a Text widget.
+
+ This is done with FormatParagraph.format.paragraph_event,
+ which calls funtions in the module as appropriate.
+ """
+ test_string = (
+ " '''this is a test of a reformat for a triple "
+ "quoted string will it reformat to less than 70 "
+ "characters for me?'''\n")
+ multiline_test_string = (
+ " '''The first line is under the max width.\n"
+ " The second line's length is way over the max width. It goes "
+ "on and on until it is over 100 characters long.\n"
+ " Same thing with the third line. It is also way over the max "
+ "width, but FormatParagraph will fix it.\n"
+ " '''\n")
+ multiline_test_comment = (
+ "# The first line is under the max width.\n"
+ "# The second line's length is way over the max width. It goes on "
+ "and on until it is over 100 characters long.\n"
+ "# Same thing with the third line. It is also way over the max "
+ "width, but FormatParagraph will fix it.\n"
+ "# The fourth line is short like the first line.")
+
+ @classmethod
+ def setUpClass(cls):
+ requires('gui')
+ cls.root = Tk()
+ editor = Editor(root=cls.root)
+ cls.text = editor.text.text # Test code does not need the wrapper.
+ cls.formatter = fp.FormatParagraph(editor).format_paragraph_event
+ # Sets the insert mark just after the re-wrapped and inserted text.
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.root.destroy()
+
+ def test_short_line(self):
+ self.text.insert('1.0', "Short line\n")
+ self.formatter("Dummy")
+ self.assertEqual(self.text.get('1.0', 'insert'), "Short line\n" )
+ self.text.delete('1.0', 'end')
+
+ def test_long_line(self):
+ text = self.text
+
+ # Set cursor ('insert' mark) to '1.0', within text.
+ text.insert('1.0', self.test_string)
+ text.mark_set('insert', '1.0')
+ self.formatter('ParameterDoesNothing')
+ result = text.get('1.0', 'insert')
+ # find function includes \n
+ expected = (
+" '''this is a test of a reformat for a triple quoted string will it\n"
+" reformat to less than 70 characters for me?'''\n") # yes
+ self.assertEqual(result, expected)
+ text.delete('1.0', 'end')
+
+ # Select from 1.11 to line end.
+ text.insert('1.0', self.test_string)
+ text.tag_add('sel', '1.11', '1.end')
+ self.formatter('ParameterDoesNothing')
+ result = text.get('1.0', 'insert')
+ # selection excludes \n
+ expected = (
+" '''this is a test of a reformat for a triple quoted string will it reformat\n"
+" to less than 70 characters for me?'''") # no
+ self.assertEqual(result, expected)
+ text.delete('1.0', 'end')
+
+ def test_multiple_lines(self):
+ text = self.text
+ # Select 2 long lines.
+ text.insert('1.0', self.multiline_test_string)
+ text.tag_add('sel', '2.0', '4.0')
+ self.formatter('ParameterDoesNothing')
+ result = text.get('2.0', 'insert')
+ expected = (
+" The second line's length is way over the max width. It goes on and\n"
+" on until it is over 100 characters long. Same thing with the third\n"
+" line. It is also way over the max width, but FormatParagraph will\n"
+" fix it.\n")
+ self.assertEqual(result, expected)
+ text.delete('1.0', 'end')
+
+ def test_comment_block(self):
+ text = self.text
+
+ # Set cursor ('insert') to '1.0', within block.
+ text.insert('1.0', self.multiline_test_comment)
+ self.formatter('ParameterDoesNothing')
+ result = text.get('1.0', 'insert')
+ expected = (
+"# The first line is under the max width. The second line's length is\n"
+"# way over the max width. It goes on and on until it is over 100\n"
+"# characters long. Same thing with the third line. It is also way over\n"
+"# the max width, but FormatParagraph will fix it. The fourth line is\n"
+"# short like the first line.\n")
+ self.assertEqual(result, expected)
+ text.delete('1.0', 'end')
+
+ # Select line 2, verify line 1 unaffected.
+ text.insert('1.0', self.multiline_test_comment)
+ text.tag_add('sel', '2.0', '3.0')
+ self.formatter('ParameterDoesNothing')
+ result = text.get('1.0', 'insert')
+ expected = (
+"# The first line is under the max width.\n"
+"# The second line's length is way over the max width. It goes on and\n"
+"# on until it is over 100 characters long.\n")
+ self.assertEqual(result, expected)
+ text.delete('1.0', 'end')
+
+# The following block worked with EditorWindow but fails with the mock.
+# Lines 2 and 3 get pasted together even though the previous block left
+# the previous line alone. More investigation is needed.
+## # Select lines 3 and 4
+## text.insert('1.0', self.multiline_test_comment)
+## text.tag_add('sel', '3.0', '5.0')
+## self.formatter('ParameterDoesNothing')
+## result = text.get('3.0', 'insert')
+## expected = (
+##"# Same thing with the third line. It is also way over the max width,\n"
+##"# but FormatParagraph will fix it. The fourth line is short like the\n"
+##"# first line.\n")
+## self.assertEqual(result, expected)
+## text.delete('1.0', 'end')
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2, exit=2)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -770,6 +770,9 @@
IDLE
----

+- Issue #18226: Add docstrings and unittests for FormatParagraph.py.
+ Original patches by Todd Rovito and Phil Webster.
+
- Issue #18279: Format - Strip trailing whitespace no longer marks a file as
changed when it has not been changed. This fix followed the addition of a
test file originally written by Phil Webster (the issue's main goal).

--
Repository URL: http://hg.python.org/cpython


python-checkins at python

Aug 10, 2013, 2:47 PM

Post #34 of 34 (2 views)
Permalink
cpython (merge 3.3 -> default): Merge with 3.3 [In reply to]

http://hg.python.org/cpython/rev/0fce8b90f25b
changeset: 85110:0fce8b90f25b
parent: 85107:b4a30d329f49
parent: 85109:9eea6401b892
user: Terry Jan Reedy <tjreedy [at] udel>
date: Sat Aug 10 17:46:48 2013 -0400
summary:
Merge with 3.3

files:
Misc/NEWS | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -770,6 +770,10 @@
IDLE
----

+- Issue #18429: Format / Format Paragraph, now works when comment blocks
+ are selected. As with text blocks, this works best when the selection
+ only includes complete lines.
+
- Issue #18226: Add docstrings and unittests for FormatParagraph.py.
Original patches by Todd Rovito and Phil Webster.


--
Repository URL: http://hg.python.org/cpython

First page Previous page 1 2 Next page Last page  View All Python checkins RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.