aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/ntpath.py
diff options
context:
space:
mode:
authorAN Long <aisk@users.noreply.github.com>2022-06-07 07:47:27 +0800
committerGitHub <noreply@github.com>2022-06-07 00:47:27 +0100
commit3256b178ed31ee8ed0c04a6e53f67d1ef96cb746 (patch)
treee7a0159b366291d657ebe5c101cbc46513b91850 /Lib/ntpath.py
parentbb0b7689465c3aac3b1d7f68c8990009462c1ae5 (diff)
downloadcpython-3256b178ed31ee8ed0c04a6e53f67d1ef96cb746.tar.gz
cpython-3256b178ed31ee8ed0c04a6e53f67d1ef96cb746.zip
bpo-42658: Use LCMapStringEx in ntpath.normcase to match OS behaviour for case-folding (GH-32010)
Diffstat (limited to 'Lib/ntpath.py')
-rw-r--r--Lib/ntpath.py42
1 files changed, 34 insertions, 8 deletions
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 041ebc75cb1..73b1bd12ddc 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -23,6 +23,7 @@ import stat
import genericpath
from genericpath import *
+
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
"getatime","getctime", "islink","exists","lexists","isdir","isfile",
@@ -41,14 +42,39 @@ def _get_bothseps(path):
# Other normalizations (such as optimizing '../' away) are not done
# (this is done by normpath).
-def normcase(s):
- """Normalize case of pathname.
-
- Makes all characters lowercase and all slashes into backslashes."""
- s = os.fspath(s)
- if isinstance(s, bytes):
- return s.replace(b'/', b'\\').lower()
- else:
+try:
+ from _winapi import (
+ LCMapStringEx as _LCMapStringEx,
+ LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT,
+ LCMAP_LOWERCASE as _LCMAP_LOWERCASE)
+
+ def normcase(s):
+ """Normalize case of pathname.
+
+ Makes all characters lowercase and all slashes into backslashes.
+ """
+ s = os.fspath(s)
+ if not s:
+ return s
+ if isinstance(s, bytes):
+ encoding = sys.getfilesystemencoding()
+ s = s.decode(encoding, 'surrogateescape').replace('/', '\\')
+ s = _LCMapStringEx(_LOCALE_NAME_INVARIANT,
+ _LCMAP_LOWERCASE, s)
+ return s.encode(encoding, 'surrogateescape')
+ else:
+ return _LCMapStringEx(_LOCALE_NAME_INVARIANT,
+ _LCMAP_LOWERCASE,
+ s.replace('/', '\\'))
+except ImportError:
+ def normcase(s):
+ """Normalize case of pathname.
+
+ Makes all characters lowercase and all slashes into backslashes.
+ """
+ s = os.fspath(s)
+ if isinstance(s, bytes):
+ return os.fsencode(os.fsdecode(s).replace('/', '\\').lower())
return s.replace('/', '\\').lower()