From 8534317f0cc47be3d02aa79dcc35a012d250076b Mon Sep 17 00:00:00 2001 From: tomruk <41700170+tomruk@users.noreply.github.com> Date: Fri, 21 Apr 2023 15:31:58 +0300 Subject: [PATCH] Add edge case: patterns that end with an escaped space --- pathspec/patterns/gitwildmatch.py | 9 ++++++++- tests/test_pathspec.py | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pathspec/patterns/gitwildmatch.py b/pathspec/patterns/gitwildmatch.py index 94d3115..3f35f2d 100644 --- a/pathspec/patterns/gitwildmatch.py +++ b/pathspec/patterns/gitwildmatch.py @@ -68,7 +68,14 @@ def pattern_to_regex( raise TypeError(f"pattern:{pattern!r} is not a unicode or byte string.") original_pattern = pattern - pattern = pattern.strip() + + if pattern.endswith('\\ '): + # EDGE CASE: Spaces can be escaped with backslash. + # If a pattern that ends with backslash followed by a space, + # only strip from left. + pattern = pattern.lstrip() + else: + pattern = pattern.strip() if pattern.startswith('#'): # A pattern starting with a hash ('#') serves as a comment diff --git a/tests/test_pathspec.py b/tests/test_pathspec.py index 1b900b0..20cbc6b 100644 --- a/tests/test_pathspec.py +++ b/tests/test_pathspec.py @@ -15,6 +15,7 @@ PathSpec) from pathspec.util import ( iter_tree_entries) +from pathspec.patterns.gitwildmatch import GitWildMatchPatternError from tests.util import ( make_dirs, make_files, @@ -119,6 +120,32 @@ def test_01_current_dir_paths(self): './src/test2/c/c.txt', }) + def test_01_empty_path(self): + """ + Tests that patterns that end with an escaped space will be treated properly. + """ + spec = PathSpec.from_lines('gitwildmatch', [ + '\\ ', + 'abc\\ ' + ]) + test_files = [ + ' ', + ' ', + 'abc ', + 'somefile', + ] + results = list(filter(spec.match_file, test_files)) + self.assertEqual(results, [ + ' ', + 'abc ' + ]) + + # An escape with double spaces is invalid. + # Disallow it. Better to be safe than sorry. + self.assertRaises(GitWildMatchPatternError, lambda: PathSpec.from_lines('gitwildmatch', [ + '\\ ' + ])) + def test_01_match_files(self): """ Tests that matching files one at a time yields the same results as