diff --git a/pycodestyle.py b/pycodestyle.py index 70263968..75c9469e 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1317,9 +1317,9 @@ def normalize_paths(value, parent=os.curdir): paths = [] for path in value.split(','): path = path.strip() - if '/' in path: + if os.path.sep in path: path = os.path.abspath(os.path.join(parent, path)) - paths.append(path.rstrip('/')) + paths.append(path.rstrip(os.path.sep)) return paths diff --git a/testsuite/test_shell.py b/testsuite/test_shell.py index 760c2284..c6d00490 100644 --- a/testsuite/test_shell.py +++ b/testsuite/test_shell.py @@ -7,6 +7,46 @@ from testsuite.support import ROOT_DIR, PseudoFile +def safe_line_split(line): + r"""Parses output lines of the form + + [location & file]:[row]:[column]:[message] + + and returns a tuple of the form + + (path, row, column, message) + + This function handles the OS-issues related to a ":" appearing in some + Windows paths. + + In Windows, the location is usually denoted as "[DriveLetter]:[location]". + On all other platforms, there is no colon in the location. + + The majority of time on windows, the line will look like: + C:\projects\pycodestyle\testsuite\E11.py:3:3: E111 indentation is ... + + Or if somebody is using a networked location + \\projects\pycodestyle\testsuite\E11.py:3:3: E111 indentation is ... + + On non-windows, the same line would looke like: + /home/projects/pycodestyle/testsuite/E11.py:3:3: E111 indentation is ... + """ + + split = line.split(':') + + if sys.platform == 'win32': # Note, even 64 bit platforms return 'win32' + if len(split) == 5: # This will be the most common + drive, path, x, y, msg = split + path = drive + ':' + path + elif len(split) == 4: # If the location is a network share + path, x, y, msg = split + else: + raise Exception("Unhandled edge case parsing message: " + line) + else: + path, x, y, msg = split + return path, x, y, msg + + class ShellTestCase(unittest.TestCase): """Test the usual CLI options and output.""" @@ -77,7 +117,7 @@ def test_check_simple(self): self.assertFalse(stderr) self.assertEqual(len(stdout), 17) for line, num, col in zip(stdout, (3, 6, 9, 12), (3, 6, 1, 5)): - path, x, y, msg = line.split(':') + path, x, y, msg = safe_line_split(line) self.assertTrue(path.endswith(E11)) self.assertEqual(x, str(num)) self.assertEqual(y, str(col)) @@ -141,7 +181,7 @@ def test_check_diff(self): self.assertEqual(errcode, 1) self.assertFalse(stderr) for line, num, col in zip(stdout, (3, 6), (3, 6)): - path, x, y, msg = line.split(':') + path, x, y, msg = safe_line_split(line) self.assertEqual(x, str(num)) self.assertEqual(y, str(col)) self.assertTrue(msg.startswith(' E11')) @@ -154,7 +194,7 @@ def test_check_diff(self): self.assertEqual(errcode, 1) self.assertFalse(stderr) for line, num, col in zip(stdout, (3, 6), (3, 6)): - path, x, y, msg = line.split(':') + path, x, y, msg = safe_line_split(line) self.assertEqual(x, str(num)) self.assertEqual(y, str(col)) self.assertTrue(msg.startswith(' E11')) diff --git a/testsuite/test_util.py b/testsuite/test_util.py index 8eaba7ef..12f67dd9 100644 --- a/testsuite/test_util.py +++ b/testsuite/test_util.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- import os import unittest - +import sys from pycodestyle import normalize_paths @@ -17,7 +17,13 @@ def test_normalize_paths(self): self.assertEqual(normalize_paths('foo'), ['foo']) self.assertEqual(normalize_paths('foo,bar'), ['foo', 'bar']) self.assertEqual(normalize_paths('foo, bar '), ['foo', 'bar']) - self.assertEqual(normalize_paths('/foo/bar,baz/../bat'), - ['/foo/bar', cwd + '/bat']) - self.assertEqual(normalize_paths(".pyc,\n build/*"), - ['.pyc', cwd + '/build/*']) + + if 'win' in sys.platform: + self.assertEqual(normalize_paths(r'C:\foo\bar,baz\..\bat'), + [r'C:\foo\bar', cwd + r'\bat']) + self.assertEqual(normalize_paths(".pyc"), ['.pyc']) + else: + self.assertEqual(normalize_paths('/foo/bar,baz/../bat'), + ['/foo/bar', cwd + '/bat']) + self.assertEqual(normalize_paths(".pyc,\n build/*"), + ['.pyc', cwd + '/build/*'])