Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
10ecbadb
Commit
10ecbadb
authored
Oct 21, 2019
by
Serhiy Storchaka
Committed by
GitHub
Oct 21, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-31202: Preserve case of literal parts in Path.glob() on Windows. (GH-16860)
parent
1e739454
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
26 additions
and
18 deletions
+26
-18
Lib/pathlib.py
Lib/pathlib.py
+20
-18
Lib/test/test_pathlib.py
Lib/test/test_pathlib.py
+4
-0
Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst
...S.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst
+2
-0
No files found.
Lib/pathlib.py
View file @
10ecbadb
...
...
@@ -187,6 +187,9 @@ class _WindowsFlavour(_Flavour):
def
casefold_parts
(
self
,
parts
):
return
[
p
.
lower
()
for
p
in
parts
]
def
compile_pattern
(
self
,
pattern
):
return
re
.
compile
(
fnmatch
.
translate
(
pattern
),
re
.
IGNORECASE
).
fullmatch
def
resolve
(
self
,
path
,
strict
=
False
):
s
=
str
(
path
)
if
not
s
:
...
...
@@ -309,6 +312,9 @@ class _PosixFlavour(_Flavour):
def
casefold_parts
(
self
,
parts
):
return
parts
def
compile_pattern
(
self
,
pattern
):
return
re
.
compile
(
fnmatch
.
translate
(
pattern
)).
fullmatch
def
resolve
(
self
,
path
,
strict
=
False
):
sep
=
self
.
sep
accessor
=
path
.
_accessor
...
...
@@ -446,7 +452,7 @@ _normal_accessor = _NormalAccessor()
# Globbing helpers
#
def
_make_selector
(
pattern_parts
):
def
_make_selector
(
pattern_parts
,
flavour
):
pat
=
pattern_parts
[
0
]
child_parts
=
pattern_parts
[
1
:]
if
pat
==
'**'
:
...
...
@@ -457,7 +463,7 @@ def _make_selector(pattern_parts):
cls
=
_WildcardSelector
else
:
cls
=
_PreciseSelector
return
cls
(
pat
,
child_parts
)
return
cls
(
pat
,
child_parts
,
flavour
)
if
hasattr
(
functools
,
"lru_cache"
):
_make_selector
=
functools
.
lru_cache
()(
_make_selector
)
...
...
@@ -467,10 +473,10 @@ class _Selector:
"""A selector matches a specific glob pattern part against the children
of a given path."""
def
__init__
(
self
,
child_parts
):
def
__init__
(
self
,
child_parts
,
flavour
):
self
.
child_parts
=
child_parts
if
child_parts
:
self
.
successor
=
_make_selector
(
child_parts
)
self
.
successor
=
_make_selector
(
child_parts
,
flavour
)
self
.
dironly
=
True
else
:
self
.
successor
=
_TerminatingSelector
()
...
...
@@ -496,9 +502,9 @@ class _TerminatingSelector:
class
_PreciseSelector
(
_Selector
):
def
__init__
(
self
,
name
,
child_parts
):
def
__init__
(
self
,
name
,
child_parts
,
flavour
):
self
.
name
=
name
_Selector
.
__init__
(
self
,
child_parts
)
_Selector
.
__init__
(
self
,
child_parts
,
flavour
)
def
_select_from
(
self
,
parent_path
,
is_dir
,
exists
,
scandir
):
try
:
...
...
@@ -512,13 +518,12 @@ class _PreciseSelector(_Selector):
class
_WildcardSelector
(
_Selector
):
def
__init__
(
self
,
pat
,
child_parts
):
self
.
pat
=
re
.
compile
(
fnmatch
.
translate
(
pat
)
)
_Selector
.
__init__
(
self
,
child_parts
)
def
__init__
(
self
,
pat
,
child_parts
,
flavour
):
self
.
match
=
flavour
.
compile_pattern
(
pat
)
_Selector
.
__init__
(
self
,
child_parts
,
flavour
)
def
_select_from
(
self
,
parent_path
,
is_dir
,
exists
,
scandir
):
try
:
cf
=
parent_path
.
_flavour
.
casefold
entries
=
list
(
scandir
(
parent_path
))
for
entry
in
entries
:
entry_is_dir
=
False
...
...
@@ -529,8 +534,7 @@ class _WildcardSelector(_Selector):
raise
if
not
self
.
dironly
or
entry_is_dir
:
name
=
entry
.
name
casefolded
=
cf
(
name
)
if
self
.
pat
.
match
(
casefolded
):
if
self
.
match
(
name
):
path
=
parent_path
.
_make_child_relpath
(
name
)
for
p
in
self
.
successor
.
_select_from
(
path
,
is_dir
,
exists
,
scandir
):
yield
p
...
...
@@ -541,8 +545,8 @@ class _WildcardSelector(_Selector):
class
_RecursiveWildcardSelector
(
_Selector
):
def
__init__
(
self
,
pat
,
child_parts
):
_Selector
.
__init__
(
self
,
child_parts
)
def
__init__
(
self
,
pat
,
child_parts
,
flavour
):
_Selector
.
__init__
(
self
,
child_parts
,
flavour
)
def
_iterate_directories
(
self
,
parent_path
,
is_dir
,
scandir
):
yield
parent_path
...
...
@@ -1118,11 +1122,10 @@ class Path(PurePath):
"""
if
not
pattern
:
raise
ValueError
(
"Unacceptable pattern: {!r}"
.
format
(
pattern
))
pattern
=
self
.
_flavour
.
casefold
(
pattern
)
drv
,
root
,
pattern_parts
=
self
.
_flavour
.
parse_parts
((
pattern
,))
if
drv
or
root
:
raise
NotImplementedError
(
"Non-relative patterns are unsupported"
)
selector
=
_make_selector
(
tuple
(
pattern_parts
))
selector
=
_make_selector
(
tuple
(
pattern_parts
)
,
self
.
_flavour
)
for
p
in
selector
.
select_from
(
self
):
yield
p
...
...
@@ -1131,11 +1134,10 @@ class Path(PurePath):
directories) matching the given relative pattern, anywhere in
this subtree.
"""
pattern
=
self
.
_flavour
.
casefold
(
pattern
)
drv
,
root
,
pattern_parts
=
self
.
_flavour
.
parse_parts
((
pattern
,))
if
drv
or
root
:
raise
NotImplementedError
(
"Non-relative patterns are unsupported"
)
selector
=
_make_selector
((
"**"
,)
+
tuple
(
pattern_parts
))
selector
=
_make_selector
((
"**"
,)
+
tuple
(
pattern_parts
)
,
self
.
_flavour
)
for
p
in
selector
.
select_from
(
self
):
yield
p
...
...
Lib/test/test_pathlib.py
View file @
10ecbadb
...
...
@@ -2378,11 +2378,15 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase):
P
=
self
.
cls
p
=
P
(
BASE
)
self
.
assertEqual
(
set
(
p
.
glob
(
"FILEa"
)),
{
P
(
BASE
,
"fileA"
)
})
self
.
assertEqual
(
set
(
p
.
glob
(
"F*a"
)),
{
P
(
BASE
,
"fileA"
)
})
self
.
assertEqual
(
set
(
map
(
str
,
p
.
glob
(
"FILEa"
))),
{
f"
{
p
}\
\
FILEa"
})
self
.
assertEqual
(
set
(
map
(
str
,
p
.
glob
(
"F*a"
))),
{
f"
{
p
}\
\
fileA"
})
def
test_rglob
(
self
):
P
=
self
.
cls
p
=
P
(
BASE
,
"dirC"
)
self
.
assertEqual
(
set
(
p
.
rglob
(
"FILEd"
)),
{
P
(
BASE
,
"dirC/dirD/fileD"
)
})
self
.
assertEqual
(
set
(
map
(
str
,
p
.
rglob
(
"FILEd"
))),
{
f"
{
p
}\
\
dirD
\
\
FILEd"
})
def
test_expanduser
(
self
):
P
=
self
.
cls
...
...
Misc/NEWS.d/next/Library/2019-10-20-12-04-48.bpo-31202.NfdIus.rst
0 → 100644
View file @
10ecbadb
The case the result of :func:`pathlib.WindowsPath.glob` matches now the case
of the pattern for literal parts.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment