|
2 | 2 |
|
3 | 3 | import unittest
|
4 | 4 | import os
|
| 5 | +import string |
5 | 6 | import warnings
|
6 | 7 |
|
7 | 8 | from fnmatch import fnmatch, fnmatchcase, translate, filter
|
@@ -91,6 +92,119 @@ def test_sep(self):
|
91 | 92 | check('usr/bin', 'usr\\bin', normsep)
|
92 | 93 | check('usr\\bin', 'usr\\bin')
|
93 | 94 |
|
| 95 | + def test_char_set(self): |
| 96 | + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') |
| 97 | + check = self.check_match |
| 98 | + tescases = string.ascii_lowercase + string.digits + string.punctuation |
| 99 | + for c in tescases: |
| 100 | + check(c, '[az]', c in 'az') |
| 101 | + check(c, '[!az]', c not in 'az') |
| 102 | + # Case insensitive. |
| 103 | + for c in tescases: |
| 104 | + check(c, '[AZ]', (c in 'az') and ignorecase) |
| 105 | + check(c, '[!AZ]', (c not in 'az') or not ignorecase) |
| 106 | + for c in string.ascii_uppercase: |
| 107 | + check(c, '[az]', (c in 'AZ') and ignorecase) |
| 108 | + check(c, '[!az]', (c not in 'AZ') or not ignorecase) |
| 109 | + # Repeated same character. |
| 110 | + for c in tescases: |
| 111 | + check(c, '[aa]', c == 'a') |
| 112 | + # Special cases. |
| 113 | + for c in tescases: |
| 114 | + check(c, '[^az]', c in '^az') |
| 115 | + check(c, '[[az]', c in '[az') |
| 116 | + check(c, r'[!]]', c != ']') |
| 117 | + check('[', '[') |
| 118 | + check('[]', '[]') |
| 119 | + check('[!', '[!') |
| 120 | + check('[!]', '[!]') |
| 121 | + |
| 122 | + def test_range(self): |
| 123 | + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') |
| 124 | + normsep = os.path.normcase('\\') == os.path.normcase('/') |
| 125 | + check = self.check_match |
| 126 | + tescases = string.ascii_lowercase + string.digits + string.punctuation |
| 127 | + for c in tescases: |
| 128 | + check(c, '[b-d]', c in 'bcd') |
| 129 | + check(c, '[!b-d]', c not in 'bcd') |
| 130 | + check(c, '[b-dx-z]', c in 'bcdxyz') |
| 131 | + check(c, '[!b-dx-z]', c not in 'bcdxyz') |
| 132 | + # Case insensitive. |
| 133 | + for c in tescases: |
| 134 | + check(c, '[B-D]', (c in 'bcd') and ignorecase) |
| 135 | + check(c, '[!B-D]', (c not in 'bcd') or not ignorecase) |
| 136 | + for c in string.ascii_uppercase: |
| 137 | + check(c, '[b-d]', (c in 'BCD') and ignorecase) |
| 138 | + check(c, '[!b-d]', (c not in 'BCD') or not ignorecase) |
| 139 | + # Upper bound == lower bound. |
| 140 | + for c in tescases: |
| 141 | + check(c, '[b-b]', c == 'b') |
| 142 | + # Special cases. |
| 143 | + for c in tescases: |
| 144 | + check(c, '[!-#]', c not in '-#') |
| 145 | + check(c, '[!--.]', c not in '-.') |
| 146 | + check(c, '[^-`]', c in '^_`') |
| 147 | + if not (normsep and c == '/'): |
| 148 | + check(c, '[[-^]', c in r'[\]^') |
| 149 | + check(c, r'[\-^]', c in r'\]^') |
| 150 | + check(c, '[b-]', c in '-b') |
| 151 | + check(c, '[!b-]', c not in '-b') |
| 152 | + check(c, '[-b]', c in '-b') |
| 153 | + check(c, '[!-b]', c not in '-b') |
| 154 | + check(c, '[-]', c in '-') |
| 155 | + check(c, '[!-]', c not in '-') |
| 156 | + # Upper bound is less that lower bound: error in RE. |
| 157 | + for c in tescases: |
| 158 | + check(c, '[d-b]', False) |
| 159 | + check(c, '[!d-b]', True) |
| 160 | + check(c, '[d-bx-z]', c in 'xyz') |
| 161 | + check(c, '[!d-bx-z]', c not in 'xyz') |
| 162 | + check(c, '[d-b^-`]', c in '^_`') |
| 163 | + if not (normsep and c == '/'): |
| 164 | + check(c, '[d-b[-^]', c in r'[\]^') |
| 165 | + |
| 166 | + def test_sep_in_char_set(self): |
| 167 | + normsep = os.path.normcase('\\') == os.path.normcase('/') |
| 168 | + check = self.check_match |
| 169 | + check('/', r'[/]') |
| 170 | + check('\\', r'[\]') |
| 171 | + check('/', r'[\]', normsep) |
| 172 | + check('\\', r'[/]', normsep) |
| 173 | + check('[/]', r'[/]', False) |
| 174 | + check(r'[\\]', r'[/]', False) |
| 175 | + check('\\', r'[\t]') |
| 176 | + check('/', r'[\t]', normsep) |
| 177 | + check('t', r'[\t]') |
| 178 | + check('\t', r'[\t]', False) |
| 179 | + |
| 180 | + def test_sep_in_range(self): |
| 181 | + normsep = os.path.normcase('\\') == os.path.normcase('/') |
| 182 | + check = self.check_match |
| 183 | + check('a/b', 'a[.-0]b', not normsep) |
| 184 | + check('a\\b', 'a[.-0]b', False) |
| 185 | + check('a\\b', 'a[Z-^]b', not normsep) |
| 186 | + check('a/b', 'a[Z-^]b', False) |
| 187 | + |
| 188 | + check('a/b', 'a[/-0]b', not normsep) |
| 189 | + check(r'a\b', 'a[/-0]b', False) |
| 190 | + check('a[/-0]b', 'a[/-0]b', False) |
| 191 | + check(r'a[\-0]b', 'a[/-0]b', False) |
| 192 | + |
| 193 | + check('a/b', 'a[.-/]b') |
| 194 | + check(r'a\b', 'a[.-/]b', normsep) |
| 195 | + check('a[.-/]b', 'a[.-/]b', False) |
| 196 | + check(r'a[.-\]b', 'a[.-/]b', False) |
| 197 | + |
| 198 | + check(r'a\b', r'a[\-^]b') |
| 199 | + check('a/b', r'a[\-^]b', normsep) |
| 200 | + check(r'a[\-^]b', r'a[\-^]b', False) |
| 201 | + check('a[/-^]b', r'a[\-^]b', False) |
| 202 | + |
| 203 | + check(r'a\b', r'a[Z-\]b', not normsep) |
| 204 | + check('a/b', r'a[Z-\]b', False) |
| 205 | + check(r'a[Z-\]b', r'a[Z-\]b', False) |
| 206 | + check('a[Z-/]b', r'a[Z-\]b', False) |
| 207 | + |
94 | 208 | def test_warnings(self):
|
95 | 209 | with warnings.catch_warnings():
|
96 | 210 | warnings.simplefilter('error', Warning)
|
|
0 commit comments