os: fsencode(), fsdecode() and os.environ(b) internal encode-decode methods
keep a local copy of the fileystem encoding, instead of calling
sys.getfilesystemencoding() each time.
The filesystem encoding is now constant.
diff --git a/Lib/os.py b/Lib/os.py
index 189579c..2e8ba92 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -487,12 +487,13 @@
data[encodekey(key)] = value
else:
# Where Env Var Names Can Be Mixed Case
+ encoding = sys.getfilesystemencoding()
def encode(value):
if not isinstance(value, str):
raise TypeError("str expected, not %s" % type(value).__name__)
- return value.encode(sys.getfilesystemencoding(), 'surrogateescape')
+ return value.encode(encoding, 'surrogateescape')
def decode(value):
- return value.decode(sys.getfilesystemencoding(), 'surrogateescape')
+ return value.decode(encoding, 'surrogateescape')
encodekey = encode
data = environ
return _Environ(data,
@@ -535,39 +536,43 @@
__all__.extend(("environb", "getenvb"))
-def fsencode(filename):
- """
- Encode filename to the filesystem encoding with 'surrogateescape' error
- handler, return bytes unchanged. On Windows, use 'strict' error handler if
- the file system encoding is 'mbcs' (which is the default encoding).
- """
- if isinstance(filename, bytes):
- return filename
- elif isinstance(filename, str):
- encoding = sys.getfilesystemencoding()
- if encoding == 'mbcs':
- return filename.encode(encoding)
- else:
- return filename.encode(encoding, 'surrogateescape')
+def _fscodec():
+ encoding = sys.getfilesystemencoding()
+ if encoding == 'mbcs':
+ errors = None # strict
else:
- raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
+ errors = 'surrogateescape'
-def fsdecode(filename):
- """
- Decode filename from the filesystem encoding with 'surrogateescape' error
- handler, return str unchanged. On Windows, use 'strict' error handler if
- the file system encoding is 'mbcs' (which is the default encoding).
- """
- if isinstance(filename, str):
- return filename
- elif isinstance(filename, bytes):
- encoding = sys.getfilesystemencoding()
- if encoding == 'mbcs':
- return filename.decode(encoding)
+ def fsencode(filename):
+ """
+ Encode filename to the filesystem encoding with 'surrogateescape' error
+ handler, return bytes unchanged. On Windows, use 'strict' error handler if
+ the file system encoding is 'mbcs' (which is the default encoding).
+ """
+ if isinstance(filename, bytes):
+ return filename
+ elif isinstance(filename, str):
+ return filename.encode(encoding, errors)
else:
- return filename.decode(encoding, 'surrogateescape')
- else:
- raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
+ raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
+
+ def fsdecode(filename):
+ """
+ Decode filename from the filesystem encoding with 'surrogateescape' error
+ handler, return str unchanged. On Windows, use 'strict' error handler if
+ the file system encoding is 'mbcs' (which is the default encoding).
+ """
+ if isinstance(filename, str):
+ return filename
+ elif isinstance(filename, bytes):
+ return filename.decode(encoding, errors)
+ else:
+ raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
+
+ return fsencode, fsdecode
+
+fsencode, fsdecode = _fscodec()
+del _fscodec
def _exists(name):
return name in globals()