diff --git a/src/Analysis/Engine/Test/BlockFormatterTests.cs b/src/Analysis/Engine/Test/BlockFormatterTests.cs new file mode 100644 index 000000000..280fea2b6 --- /dev/null +++ b/src/Analysis/Engine/Test/BlockFormatterTests.cs @@ -0,0 +1,304 @@ +// Python Tools for Visual Studio +// Copyright(c) Microsoft Corporation +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the License); you may not use +// this file except in compliance with the License. You may obtain a copy of the +// License at http://www.apache.org/licenses/LICENSE-2.0 +// +// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY +// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +// MERCHANTABLITY OR NON-INFRINGEMENT. +// +// See the Apache Version 2.0 License for specific language governing +// permissions and limitations under the License. + +using System; +using System.IO; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.Python.LanguageServer; +using Microsoft.Python.LanguageServer.Implementation; +using Microsoft.PythonTools.Analysis; +using Microsoft.PythonTools.Analysis.FluentAssertions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TestUtilities; + +namespace AnalysisTests { + [TestClass] + public class BlockFormatterTests { + public TestContext TestContext { get; set; } + + [TestInitialize] + public void TestInitialize() { + TestEnvironmentImpl.TestInitialize($"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}"); + } + + [TestCleanup] + public void TestCleanup() { + TestEnvironmentImpl.TestCleanup(); + } + + [TestMethod, Priority(0)] + public void NullReader() { + Func> func = () => BlockFormatter.ProvideEdits(null, new Position(), new FormattingOptions()); + func.Should().Throw().And.ParamName.Should().Be("reader"); + } + + [TestMethod, Priority(0)] + public async Task FirstLine() { + using (var reader = new StringReader(string.Empty)) { + var edits = await BlockFormatter.ProvideEdits(reader, new Position { line = 0, character = 4 }, new FormattingOptions()); + edits.Should().BeEmpty(); + } + } + + [TestMethod, Priority(0)] + public void TooShort() { + using (var reader = new StringReader("a + b")) { + Func> func = () => BlockFormatter.ProvideEdits(reader, new Position { line = 1, character = 4 }, new FormattingOptions()); + func.Should().Throw().And.ParamName.Should().Be("position"); + } + } + + [TestMethod, Priority(0)] + public async Task NoMatch() { + var code = @"d = { + 'a': a, + 'b': +"; + using (var reader = new StringReader(code)) { + var edits = await BlockFormatter.ProvideEdits(reader, new Position { line = 2, character = 7 }, new FormattingOptions()); + edits.Should().BeEmpty(); + } + } + + [DataRow("elseBlocksFirstLine2.py", 3, 7, true, 2, 0, 2)] + [DataRow("elseBlocksFirstLine4.py", 3, 9, true, 4, 0, 4)] + [DataRow("elseBlocksFirstLineTab.py", 3, 6, false, 4, 0, 1)] + [DataTestMethod, Priority(0)] + public async Task ElseBlock(string filename, int line, int col, bool insertSpaces, int tabSize, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = insertSpaces, tabSize = tabSize }; + + var src = TestData.GetPath("TestData", "Formatting", filename); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(string.Empty, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(6, 22, 0, 2)] + [DataRow(35, 13, 0, 2)] + [DataRow(54, 19, 0, 2)] + [DataRow(76, 9, 0, 2)] + [DataRow(143, 22, 0, 2)] + [DataRow(172, 11, 0, 2)] + [DataRow(195, 12, 0, 2)] + [DataTestMethod, Priority(0)] + public async Task TryBlockTwoSpace(int line, int col, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 2 }; + + var src = TestData.GetPath("TestData", "Formatting", "tryBlocks2.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(string.Empty, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(15, 21)] + [DataRow(47, 12)] + [DataRow(157, 25)] + [DataTestMethod, Priority(0)] + public async Task TryBlockTwoSpaceNoEdits(int line, int col) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 2 }; + + var src = TestData.GetPath("TestData", "Formatting", "tryBlocks2.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().BeEmpty(); + } + } + + [DataRow(6, 22, 0, 4)] + [DataRow(35, 13, 0, 4)] + [DataRow(54, 19, 0, 4)] + [DataRow(76, 9, 0, 4)] + [DataRow(143, 22, 0, 4)] + [DataRow(172, 11, 0, 4)] + [DataRow(195, 12, 0, 4)] + [DataTestMethod, Priority(0)] + public async Task TryBlockFourSpace(int line, int col, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 4 }; + + var src = TestData.GetPath("TestData", "Formatting", "tryBlocks4.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(string.Empty, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(15, 21)] + [DataRow(47, 12)] + [DataRow(157, 25)] + [DataTestMethod, Priority(0)] + public async Task TryBlockFourSpaceNoEdits(int line, int col) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 4 }; + + var src = TestData.GetPath("TestData", "Formatting", "tryBlocks4.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().BeEmpty(); + } + } + + [DataRow(6, 22, 0, 2)] + [DataRow(35, 13, 0, 2)] + [DataRow(54, 19, 0, 2)] + [DataRow(76, 9, 0, 2)] + [DataRow(143, 22, 0, 2)] + [DataRow(172, 11, 0, 3)] + [DataRow(195, 12, 0, 2)] + [DataTestMethod, Priority(0)] + public async Task TryBlockTab(int line, int col, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = false, tabSize = 4 }; + + var src = TestData.GetPath("TestData", "Formatting", "tryBlocksTab.py"); + var newText = new string('\t', endCharacter - 1); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(newText, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(4, 18, 0, 2)] + [DataRow(7, 18, 0, 2)] + [DataRow(21, 18, 0, 2)] + [DataRow(38, 7, 0, 2)] + [DataRow(47, 13, 0, 2)] + [DataRow(57, 9, 0, 2)] + [DataRow(66, 20, 0, 2)] + [DataRow(69, 20, 0, 2)] + [DataRow(83, 20, 0, 2)] + [DataRow(109, 15, 0, 2)] + [DataRow(119, 11, 0, 2)] + [DataRow(134, 9, 0, 2)] + [DataTestMethod, Priority(0)] + public async Task ElseBlockTwoSpace(int line, int col, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 2 }; + + var src = TestData.GetPath("TestData", "Formatting", "elseBlocks2.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(string.Empty, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(345, 18)] + [DataRow(359, 18)] + [DataTestMethod, Priority(0)] + public async Task ElseBlockTwoSpaceNoEdits(int line, int col) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 2 }; + + var src = TestData.GetPath("TestData", "Formatting", "elseBlocks2.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().BeEmpty(); + } + } + + [DataRow(4, 18, 0, 4)] + [DataRow(7, 18, 0, 4)] + [DataRow(21, 18, 0, 4)] + [DataRow(38, 7, 0, 4)] + [DataRow(47, 13, 0, 4)] + [DataRow(57, 9, 0, 4)] + [DataRow(66, 20, 0, 4)] + [DataRow(69, 20, 0, 4)] + [DataRow(83, 20, 0, 4)] + [DataRow(109, 15, 0, 4)] + [DataRow(119, 11, 0, 4)] + [DataRow(134, 9, 0, 4)] + [DataTestMethod, Priority(0)] + public async Task ElseBlockFourSpace(int line, int col, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 4 }; + + var src = TestData.GetPath("TestData", "Formatting", "elseBlocks4.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(string.Empty, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(345, 18)] + [DataTestMethod, Priority(0)] + public async Task ElseBlockFourSpaceNoEdits(int line, int col) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 4 }; + + var src = TestData.GetPath("TestData", "Formatting", "elseBlocks4.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().BeEmpty(); + } + } + + [DataRow(4, 18, 0, 1)] + [DataRow(7, 18, 0, 1)] + [DataRow(21, 18, 0, 1)] + [DataRow(38, 7, 0, 1)] + [DataRow(47, 13, 0, 1)] + [DataRow(57, 9, 0, 1)] + [DataRow(66, 20, 0, 1)] + [DataRow(69, 20, 0, 1)] + [DataRow(83, 20, 0, 1)] + [DataRow(109, 15, 0, 1)] + [DataRow(119, 11, 0, 1)] + [DataRow(134, 9, 0, 1)] + [DataTestMethod, Priority(0)] + public async Task ElseBlockTab(int line, int col, int startCharacter, int endCharacter) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 2 }; + + var src = TestData.GetPath("TestData", "Formatting", "elseBlocksTab.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().OnlyHaveTextEdit(string.Empty, (line, startCharacter, line, endCharacter)); + } + } + + [DataRow(345, 18)] + [DataTestMethod, Priority(0)] + public async Task ElseBlockTabNoEdits(int line, int col) { + var position = new Position { line = line, character = col }; + var options = new FormattingOptions { insertSpaces = true, tabSize = 2 }; + + var src = TestData.GetPath("TestData", "Formatting", "elseBlocksTab.py"); + + using (var reader = new StreamReader(src)) { + var edits = await BlockFormatter.ProvideEdits(reader, position, options); + edits.Should().BeEmpty(); + } + } + } +} diff --git a/src/Analysis/Engine/Test/LanguageServerTests.cs b/src/Analysis/Engine/Test/LanguageServerTests.cs index 4cd1fdc16..715a663a8 100644 --- a/src/Analysis/Engine/Test/LanguageServerTests.cs +++ b/src/Analysis/Engine/Test/LanguageServerTests.cs @@ -991,7 +991,7 @@ public async Task ParseAndAnalysisDiagnostics() { } [TestMethod, Priority(0)] - public async Task OnTypeFormatting() { + public async Task OnTypeFormattingLine() { using (var s = await CreateServer()) { var uri = await AddModule(s, "def foo ( ) :\n x = a + b\n x+= 1"); @@ -1008,6 +1008,16 @@ public async Task OnTypeFormatting() { } } + [TestMethod, Priority(0)] + public async Task OnTypeFormattingBlock() { + using (var s = await CreateServer()) { + var uri = await AddModule(s, "if x:\n pass\n else:"); + + var edits = await s.SendDocumentOnTypeFormatting(uri, new SourceLocation(3, 9), ":"); + edits.Should().OnlyHaveTextEdit("", (2, 0, 2, 4)); + } + } + class GetAllExtensionProvider : ILanguageServerExtensionProvider { public Task CreateAsync(IPythonLanguageServer server, IReadOnlyDictionary properties, CancellationToken cancellationToken) { return Task.FromResult(new GetAllExtension((Server)server, properties)); diff --git a/src/LanguageServer/Impl/Implementation/BlockFormatter.cs b/src/LanguageServer/Impl/Implementation/BlockFormatter.cs new file mode 100644 index 000000000..b03cfeda3 --- /dev/null +++ b/src/LanguageServer/Impl/Implementation/BlockFormatter.cs @@ -0,0 +1,172 @@ +// Python Tools for Visual Studio +// Copyright(c) Microsoft Corporation +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the License); you may not use +// this file except in compliance with the License. You may obtain a copy of the +// License at http://www.apache.org/licenses/LICENSE-2.0 +// +// THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY +// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +// MERCHANTABLITY OR NON-INFRINGEMENT. +// +// See the Apache Version 2.0 License for specific language governing +// permissions and limitations under the License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.PythonTools.Analysis; +using Microsoft.PythonTools.Analysis.Infrastructure; + +namespace Microsoft.Python.LanguageServer.Implementation { + /// + /// Port of BlockFormatProviders in vscode-python. + /// + internal class BlockFormatter { + private static readonly Regex IfRegex = CompileRegex(@"^( |\t)*if +.*: *$"); + private static readonly Regex ElIfRegex = CompileRegex(@"^( |\t)*elif +.*: *$"); + private static readonly Regex ElseRegex = CompileRegex(@"^( |\t)*else *: *$"); + private static readonly Regex ForInRegex = CompileRegex(@"^( |\t)*for \w in .*: *$"); + private static readonly Regex AsyncForInRegex = CompileRegex(@"^( |\t)*async *for \w in .*: *$"); + private static readonly Regex WhileRegex = CompileRegex(@"^( |\t)*while .*: *$"); + private static readonly Regex TryRegex = CompileRegex(@"^( |\t)*try *: *$"); + private static readonly Regex FinallyRegex = CompileRegex(@"^( |\t)*finally *: *$"); + private static readonly Regex ExceptRegex = CompileRegex(@"^( |\t)*except *\w* *(as)? *\w* *: *$"); + private static readonly Regex DefRegex = CompileRegex(@"^( |\t)*def \w *\(.*$"); + private static readonly Regex AsyncDefRegex = CompileRegex(@"^( |\t)*async *def \w *\(.*$"); + private static readonly Regex ClassRegex = CompileRegex(@"^( |\t)*class *\w* *.*: *$"); + + private static readonly IEnumerable BoundaryBlocks = new[] { DefRegex, AsyncDefRegex, ClassRegex }; + + private static readonly IEnumerable Formatters = new[] { + new BlockFormatter(ElseRegex, new[] { IfRegex, ElIfRegex, ForInRegex, AsyncForInRegex, WhileRegex, TryRegex, ExceptRegex }), + new BlockFormatter(ElIfRegex, new[] { IfRegex, ElIfRegex }), + new BlockFormatter(ExceptRegex, new[] { TryRegex, ExceptRegex }), + new BlockFormatter(ExceptRegex, new[] { TryRegex, ExceptRegex }), + new BlockFormatter(FinallyRegex, new[] { TryRegex, ExceptRegex }), + }; + + public static async Task ProvideEdits(TextReader reader, Position position, FormattingOptions options) { + Check.ArgumentNull(nameof(reader), reader); + Check.ArgumentOutOfRange(nameof(position), () => position.line < 0); + + if (position.line == 0) { + return Array.Empty(); + } + + var lines = new List(position.line + 1); + + for (var i = 0; i <= position.line; i++) { + var curr = await reader.ReadLineAsync(); + + if (curr == null) { + throw new ArgumentException($"reached end of file before {nameof(position)}", nameof(position)); + } + + lines.Add(curr); + } + + var line = lines[position.line]; + var prevLine = lines[position.line - 1]; + + // We're only interested in cases where the current block is at the same indentation level as the previous line + // E.g. if we have an if..else block, generally the else statement would be at the same level as the code in the if... + if (FirstNonWhitespaceCharacterIndex(line) != FirstNonWhitespaceCharacterIndex(prevLine)) { + return Array.Empty(); + } + + var formatter = Formatters.FirstOrDefault(f => f.CanProvideEdits(line)); + if (formatter == null) { + return Array.Empty(); + } + + return formatter.ProvideEdits(lines, position, options); + } + + private readonly Regex _blockRegexp; + private readonly IEnumerable _previousBlockRegexps; + + private BlockFormatter(Regex blockRegexp, IEnumerable previousBlockRegexps) { + Check.ArgumentNull(nameof(blockRegexp), blockRegexp); + Check.Argument(nameof(previousBlockRegexps), () => !previousBlockRegexps.IsNullOrEmpty()); + + _blockRegexp = blockRegexp; + _previousBlockRegexps = previousBlockRegexps; + } + + private bool CanProvideEdits(string line) => _blockRegexp.IsMatch(line); + + private TextEdit[] ProvideEdits(IList lines, Position position, FormattingOptions options) { + var line = lines[position.line]; + var lineFirstNonWhitespace = FirstNonWhitespaceCharacterIndex(line); + + // We can have else for the following blocks: + // if: + // elif x: + // for x in y: + // while x: + + // We need to find a block statement that is less than or equal to this statement block (but not greater) + for (var lineNum = position.line - 1; lineNum >= 0; lineNum--) { + var prevLine = lines[lineNum]; + + // Oops, we've reached a boundary (like the function or class definition) + // Get out of here + if (BoundaryBlocks.Any(regexp => regexp.IsMatch(prevLine))) { + return Array.Empty(); + } + + var blockRegex = _previousBlockRegexps.FirstOrDefault(regex => regex.IsMatch(prevLine)); + if (blockRegex == null) { + continue; + } + + var startOfBlockInLine = FirstNonWhitespaceCharacterIndex(prevLine); + if (startOfBlockInLine > lineFirstNonWhitespace) { + continue; + } + + var startPosition = new Position { line = position.line, character = 0 }; + var endPosition = new Position { line = position.line, character = lineFirstNonWhitespace - startOfBlockInLine }; + + if (endPosition.character == 0) { + // current block cannot be at the same level as a preivous block + continue; + } + + if (options.insertSpaces) { + return new[] { + new TextEdit { + range = new Range {start = startPosition, end = endPosition }, + newText = string.Empty + } + }; + } + + // Delete everything before the block and insert the same characters we have in the previous block + var prefixOfPreviousBlock = prevLine.Substring(0, startOfBlockInLine); + + return new[] { + new TextEdit { + range = new Range { + start = startPosition, + end = new Position {line = position.line, character = lineFirstNonWhitespace } + }, + newText = prefixOfPreviousBlock + } + }; + } + + return Array.Empty(); + } + + private static int FirstNonWhitespaceCharacterIndex(string s) => s.TakeWhile(char.IsWhiteSpace).Count(); + + private static Regex CompileRegex(string pattern) => new Regex(pattern, RegexOptions.Compiled); + } +} diff --git a/src/LanguageServer/Impl/Implementation/Server.OnTypeFormatting.cs b/src/LanguageServer/Impl/Implementation/Server.OnTypeFormatting.cs index 046596b21..f8de29250 100644 --- a/src/LanguageServer/Impl/Implementation/Server.OnTypeFormatting.cs +++ b/src/LanguageServer/Impl/Implementation/Server.OnTypeFormatting.cs @@ -21,14 +21,15 @@ namespace Microsoft.Python.LanguageServer.Implementation { public sealed partial class Server { - public override Task DocumentOnTypeFormatting(DocumentOnTypeFormattingParams @params, CancellationToken cancellationToken) { - int targetLine; // One-indexed line number + public override async Task DocumentOnTypeFormatting(DocumentOnTypeFormattingParams @params, CancellationToken cancellationToken) { + int targetLine; switch (@params.ch) { case "\n": targetLine = @params.position.line - 1; break; case ";": + case ":": targetLine = @params.position.line; break; default: @@ -38,13 +39,17 @@ public override Task DocumentOnTypeFormatting(DocumentOnTypeFormatti var uri = @params.textDocument.uri; if (!(ProjectFiles.GetEntry(uri) is IDocument doc)) { - return Task.FromResult(Array.Empty()); + return Array.Empty(); } var part = ProjectFiles.GetPart(uri); using (var reader = doc.ReadDocument(part, out _)) { + if (@params.ch == ":") { + return await BlockFormatter.ProvideEdits(reader, @params.position, @params.options); + } + var lineFormatter = new LineFormatter(reader, Analyzer.LanguageVersion); - return Task.FromResult(lineFormatter.FormatLine(targetLine)); + return lineFormatter.FormatLine(targetLine); } } } diff --git a/src/LanguageServer/Impl/Implementation/Server.cs b/src/LanguageServer/Impl/Implementation/Server.cs index 10940c63e..9c88428dd 100644 --- a/src/LanguageServer/Impl/Implementation/Server.cs +++ b/src/LanguageServer/Impl/Implementation/Server.cs @@ -148,10 +148,10 @@ public void TraceMessage(IFormattable message) { workspaceSymbolProvider = true, documentSymbolProvider = true, renameProvider = true, - //documentOnTypeFormattingProvider = new DocumentOnTypeFormattingOptions { - // firstTriggerCharacter = "\n", - // moreTriggerCharacter = new[] { ";" } - //}, + documentOnTypeFormattingProvider = new DocumentOnTypeFormattingOptions { + firstTriggerCharacter = "\n", + moreTriggerCharacter = new[] { ";", ":" } + }, } }; diff --git a/src/UnitTests/TestData/Formatting/elseBlocks2.py b/src/UnitTests/TestData/Formatting/elseBlocks2.py new file mode 100644 index 000000000..da4614982 --- /dev/null +++ b/src/UnitTests/TestData/Formatting/elseBlocks2.py @@ -0,0 +1,365 @@ +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var +elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var +elif var == 150: + print "2 - Got a true expression value" + print var +elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def test(): + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + else: + pass + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def minus(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + finally: + print("executing finally clause") + +class DoSomething(): + def test(): + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + else: + pass + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def minus(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + finally: + print("executing finally clause") + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + if var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var diff --git a/src/UnitTests/TestData/Formatting/elseBlocks4.py b/src/UnitTests/TestData/Formatting/elseBlocks4.py new file mode 100644 index 000000000..c8213d6c4 --- /dev/null +++ b/src/UnitTests/TestData/Formatting/elseBlocks4.py @@ -0,0 +1,351 @@ +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var +elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var +elif var == 150: + print "2 - Got a true expression value" + print var +elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def test(): + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + else: + pass + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def minus(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + finally: + print("executing finally clause") + +class DoSomething(): + def test(): + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + else: + pass + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def minus(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + finally: + print("executing finally clause") + + var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var diff --git a/src/UnitTests/TestData/Formatting/elseBlocksFirstLine2.py b/src/UnitTests/TestData/Formatting/elseBlocksFirstLine2.py new file mode 100644 index 000000000..b99c1738d --- /dev/null +++ b/src/UnitTests/TestData/Formatting/elseBlocksFirstLine2.py @@ -0,0 +1,4 @@ +if True == True: + a = 2 + b = 3 + else: \ No newline at end of file diff --git a/src/UnitTests/TestData/Formatting/elseBlocksFirstLine4.py b/src/UnitTests/TestData/Formatting/elseBlocksFirstLine4.py new file mode 100644 index 000000000..64ad7dfb7 --- /dev/null +++ b/src/UnitTests/TestData/Formatting/elseBlocksFirstLine4.py @@ -0,0 +1,4 @@ +if True == True: + a = 2 + b = 3 + else: \ No newline at end of file diff --git a/src/UnitTests/TestData/Formatting/elseBlocksFirstLineTab.py b/src/UnitTests/TestData/Formatting/elseBlocksFirstLineTab.py new file mode 100644 index 000000000..39cea5e8c --- /dev/null +++ b/src/UnitTests/TestData/Formatting/elseBlocksFirstLineTab.py @@ -0,0 +1,4 @@ +if True == True: + a = 2 + b = 3 + else: \ No newline at end of file diff --git a/src/UnitTests/TestData/Formatting/elseBlocksTab.py b/src/UnitTests/TestData/Formatting/elseBlocksTab.py new file mode 100644 index 000000000..e92233ea9 --- /dev/null +++ b/src/UnitTests/TestData/Formatting/elseBlocksTab.py @@ -0,0 +1,351 @@ +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var +elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var + +var = 100 +if var == 200: + print "1 - Got a true expression value" + print var +elif var == 150: + print "2 - Got a true expression value" + print var +elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def test(): + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + else: + pass + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def minus(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + finally: + print("executing finally clause") + +class DoSomething(): + def test(): + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + var = 100 + if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var + else: + print "4 - Got a false expression value" + print var + + for n in range(2, 10): + for x in range(2, n): + if n % x == 0: + print n, 'equals', x, '*', n/x + break + else: + # loop fell through without finding a factor + print n, 'is a prime number' + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + else: + pass + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def minus(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #except should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + + def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + finally: + print("executing finally clause") + + var = 100 +if var == 200: + print "1 - Got a true expression value" + print var + elif var == 150: + print "2 - Got a true expression value" + print var + elif var == 100: + print "3 - Got a true expression value" + print var +else: + print "4 - Got a false expression value" + print var diff --git a/src/UnitTests/TestData/Formatting/tryBlocks2.py b/src/UnitTests/TestData/Formatting/tryBlocks2.py new file mode 100644 index 000000000..504feeeb3 --- /dev/null +++ b/src/UnitTests/TestData/Formatting/tryBlocks2.py @@ -0,0 +1,208 @@ + +while True: + try: + x = int(input("Please enter a number: ")) + break + # except should be in same column as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + + +while True: + try: + x = int(input("Please enter a number: ")) + break + # except should be in same column as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + +class B(Exception): + pass + +class C(B): + pass + +class D(C): + pass + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + # except should be in same level as except + except B: + print("B") + + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + # except should be in same level as except + except B: + print("B") + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + #except should be in same level as try + except IOError: + print('cannot open', arg) + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + #except should be in same level as try + except IOError: + print('cannot open', arg) + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def minus(): + while True: + try: + x = int(input("Please enter a number: ")) + break + #except should be in same level as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + +def minus(): + while True: + try: + x = int(input("Please enter a number: ")) + break + #except should be in same level as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + + +def zero(): + for cls in [B, C, D]: + try: + raise cls() + #except should be in same level as try: + except D: + print("D") + except C: + print("C") + except B: + print("B") + +def zero(): + for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + #except should be in same level as try: + except C: + print("C") + except B: + print("B") + +def one(): + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + except OSError as err: + print("OS error: {0}".format(err)) + # except should be in same level as except + except ValueError: + print("Could not convert data to an integer.") + except: + print("Unexpected error:", sys.exc_info()[0]) + raise + +def one(): + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + # except should be in same level as except + except OSError as err: + print("OS error: {0}".format(err)) + except ValueError: + print("Could not convert data to an integer.") + except: + print("Unexpected error:", sys.exc_info()[0]) + raise + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + # finally should be in same level as except + finally: + print("executing finally clause") + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + # finally should be in same level as except + finally: + print("executing finally clause") \ No newline at end of file diff --git a/src/UnitTests/TestData/Formatting/tryBlocks4.py b/src/UnitTests/TestData/Formatting/tryBlocks4.py new file mode 100644 index 000000000..ce9e444ca --- /dev/null +++ b/src/UnitTests/TestData/Formatting/tryBlocks4.py @@ -0,0 +1,208 @@ + +while True: + try: + x = int(input("Please enter a number: ")) + break + # except should be in same column as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + + +while True: + try: + x = int(input("Please enter a number: ")) + break + # except should be in same column as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + +class B(Exception): + pass + +class C(B): + pass + +class D(C): + pass + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + # except should be in same level as except + except B: + print("B") + + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + # except should be in same level as except + except B: + print("B") + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + #except should be in same level as try + except IOError: + print('cannot open', arg) + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + #except should be in same level as try + except IOError: + print('cannot open', arg) + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def minus(): + while True: + try: + x = int(input("Please enter a number: ")) + break + #except should be in same level as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + +def minus(): + while True: + try: + x = int(input("Please enter a number: ")) + break + #except should be in same level as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + + +def zero(): + for cls in [B, C, D]: + try: + raise cls() + #except should be in same level as try: + except D: + print("D") + except C: + print("C") + except B: + print("B") + +def zero(): + for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + #except should be in same level as try: + except C: + print("C") + except B: + print("B") + +def one(): + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + except OSError as err: + print("OS error: {0}".format(err)) + # except should be in same level as except + except ValueError: + print("Could not convert data to an integer.") + except: + print("Unexpected error:", sys.exc_info()[0]) + raise + +def one(): + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + # except should be in same level as except + except OSError as err: + print("OS error: {0}".format(err)) + except ValueError: + print("Could not convert data to an integer.") + except: + print("Unexpected error:", sys.exc_info()[0]) + raise + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + # finally should be in same level as except + finally: + print("executing finally clause") + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + # finally should be in same level as except + finally: + print("executing finally clause") \ No newline at end of file diff --git a/src/UnitTests/TestData/Formatting/tryBlocksTab.py b/src/UnitTests/TestData/Formatting/tryBlocksTab.py new file mode 100644 index 000000000..d94e057d4 --- /dev/null +++ b/src/UnitTests/TestData/Formatting/tryBlocksTab.py @@ -0,0 +1,208 @@ + +while True: + try: + x = int(input("Please enter a number: ")) + break + # except should be in same column as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + + +while True: + try: + x = int(input("Please enter a number: ")) + break + # except should be in same column as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + +class B(Exception): + pass + +class C(B): + pass + +class D(C): + pass + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + # except should be in same level as except + except B: + print("B") + + +for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + except C: + print("C") + # except should be in same level as except + except B: + print("B") + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + #except should be in same level as try + except IOError: + print('cannot open', arg) + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + #except should be in same level as try + except IOError: + print('cannot open', arg) + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + #else should be in same level as try + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def minus(): + while True: + try: + x = int(input("Please enter a number: ")) + break + #except should be in same level as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + +def minus(): + while True: + try: + x = int(input("Please enter a number: ")) + break + #except should be in same level as try: + except ValueError: + print("Oops! That was no valid number. Try again...") + + +def zero(): + for cls in [B, C, D]: + try: + raise cls() + #except should be in same level as try: + except D: + print("D") + except C: + print("C") + except B: + print("B") + +def zero(): + for cls in [B, C, D]: + try: + raise cls() + except D: + print("D") + #except should be in same level as try: + except C: + print("C") + except B: + print("B") + +def one(): + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + except OSError as err: + print("OS error: {0}".format(err)) + # except should be in same level as except + except ValueError: + print("Could not convert data to an integer.") + except: + print("Unexpected error:", sys.exc_info()[0]) + raise + +def one(): + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + # except should be in same level as except + except OSError as err: + print("OS error: {0}".format(err)) + except ValueError: + print("Could not convert data to an integer.") + except: + print("Unexpected error:", sys.exc_info()[0]) + raise + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def two(): + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print('cannot open', arg) + # else should be in same level as except + else: + print(arg, 'has', len(f.readlines()), 'lines') + f.close() + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + # finally should be in same level as except + finally: + print("executing finally clause") + +def divide(x, y): + try: + result = x / y + except ZeroDivisionError: + print("division by zero!") + else: + print("result is", result) + # finally should be in same level as except + finally: + print("executing finally clause") \ No newline at end of file