Skip to content

Commit e32415c

Browse files
gh-160900: document path-like support and test mixed filename types
1 parent c2f1cb1 commit e32415c

2 files changed

Lines changed: 33 additions & 13 deletions

File tree

‎Doc/library/fnmatch.rst‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ module. See module :mod:`glob` for pathname expansion (:mod:`glob` uses
4646
a period are not special for this module, and are matched by the ``*`` and ``?``
4747
patterns.
4848

49-
Unless stated otherwise, "filename string" and "pattern string" either refer to
50-
:class:`str` or ``ISO-8859-1`` encoded :class:`bytes` objects. Note that the
49+
Unless stated otherwise, "filename string" and "pattern string" refer to
50+
:class:`str` or ``ISO-8859-1`` encoded :class:`bytes` objects.
51+
In addition to filename strings, :func:`.filter` and :func:`.filterfalse`
52+
accept :term:`path-like objects <path-like object>` in *names*. Note that the
5153
functions documented below do not allow to mix a :class:`!bytes` pattern with
5254
a :class:`!str` filename, and vice-versa.
5355

@@ -85,29 +87,27 @@ functions: :func:`~fnmatch.fnmatch`, :func:`fnmatchcase`, :func:`.filter`,
8587

8688
.. function:: filter(names, pat)
8789

88-
Construct a list from those elements of the :term:`iterable` of filenames
89-
*names* that match the pattern string *pat*.
90+
Construct a list from those elements of the :term:`iterable` of filename
91+
strings *names* that match the pattern string *pat*.
9092
It is the same as ``[n for n in names if fnmatch(n, pat)]``,
9193
but implemented more efficiently.
9294

93-
The filenames may be strings or path-like objects. Each filename is
94-
normalized using :func:`os.path.normcase` for matching; the original
95-
objects are preserved in the returned list.
95+
.. versionchanged:: next
96+
Added support for path-like objects in *names*.
9697

9798

9899
.. function:: filterfalse(names, pat)
99100

100-
Construct a list from those elements of the :term:`iterable` of filenames
101-
*names* that do not match the pattern string *pat*.
101+
Construct a list from those elements of the :term:`iterable` of filename
102+
strings *names* that do not match the pattern string *pat*.
102103
It is the same as ``[n for n in names if not fnmatch(n, pat)]``,
103104
but implemented more efficiently.
104105

105-
The filenames may be strings or path-like objects. Each filename is
106-
normalized using :func:`os.path.normcase` for matching; the original
107-
objects are preserved in the returned list.
108-
109106
.. versionadded:: 3.14
110107

108+
.. versionchanged:: next
109+
Added support for path-like objects in *names*.
110+
111111

112112
.. function:: translate(pat)
113113

‎Lib/test/test_fnmatch.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,16 @@ def test_mix_bytes_str(self):
332332
self.assertRaises(TypeError, filter, ['test'], b'*')
333333
self.assertRaises(TypeError, filter, [b'test'], '*')
334334

335+
336+
def test_mix_bytes_str_pathlike(self):
337+
path = pathlib.Path("test")
338+
self.assertRaises(TypeError, filter, [path], b'*')
339+
self.assertRaises(TypeError, filter, [path, b'test'], '*')
340+
self.assertRaises(TypeError, filter, [b'test', path], '*')
341+
self.assertRaises(TypeError, filter, [path, 'test'], b'*')
342+
self.assertRaises(TypeError, filter, ['test', path], b'*')
343+
self.assertEqual(filter([path, 'other'], 'te*'), [path])
344+
335345
def test_case(self):
336346
self.assertEqual(filter(['Test.py', 'Test.rb', 'Test.PL'], '*.p*'),
337347
['Test.py', 'Test.PL'] if IGNORECASE else ['Test.py'])
@@ -360,6 +370,16 @@ def test_mix_bytes_str(self):
360370
self.assertRaises(TypeError, filterfalse, ['test'], b'*')
361371
self.assertRaises(TypeError, filterfalse, [b'test'], '*')
362372

373+
374+
def test_mix_bytes_str_pathlike(self):
375+
path = pathlib.Path("test")
376+
self.assertRaises(TypeError, filterfalse, [path], b'*')
377+
self.assertRaises(TypeError, filterfalse, [path, b'test'], '*')
378+
self.assertRaises(TypeError, filterfalse, [b'test', path], '*')
379+
self.assertRaises(TypeError, filterfalse, [path, 'test'], b'*')
380+
self.assertRaises(TypeError, filterfalse, ['test', path], b'*')
381+
self.assertEqual(filterfalse([path, 'other'], 'te*'), ['other'])
382+
363383
def test_case(self):
364384
self.assertEqual(filterfalse(['Test.py', 'Test.rb', 'Test.PL'], '*.p*'),
365385
['Test.rb'] if IGNORECASE else ['Test.rb', 'Test.PL'])

0 commit comments

Comments
 (0)