https://github.com/python/cpython/commit/cae4cdd07ddfcd8bcc05d683bac53815391c9907
commit: cae4cdd07ddfcd8bcc05d683bac53815391c9907
branch: main
author: Nice Zombies <[email protected]>
committer: AlexWaygood <[email protected]>
date: 2024-04-02T21:32:35+01:00
summary:

gh-117349: Micro-optimize a few `os.path` functions (#117350)

Co-authored-by: Alex Waygood <[email protected]>
Co-authored-by: Barney Gale <[email protected]>
Co-authored-by: Pieter Eendebak <[email protected]>

files:
A Misc/NEWS.d/next/Core and 
Builtins/2024-03-29-15-04-13.gh-issue-117349.OB9kQQ.rst
M Lib/ntpath.py
M Lib/posixpath.py
M Misc/ACKS

diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index ecfc7d48dbb192..0650f14f89f10b 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -102,11 +102,11 @@ def join(path, *paths):
     if isinstance(path, bytes):
         sep = b'\\'
         seps = b'\\/'
-        colon = b':'
+        colon_seps = b':\\/'
     else:
         sep = '\\'
         seps = '\\/'
-        colon = ':'
+        colon_seps = ':\\/'
     try:
         if not paths:
             path[:0] + sep  #23780: Ensure compatible data type even if p is 
null.
@@ -135,7 +135,7 @@ def join(path, *paths):
             result_path = result_path + p_path
         ## add separator between UNC and non-absolute path
         if (result_path and not result_root and
-            result_drive and result_drive[-1:] not in colon + seps):
+            result_drive and result_drive[-1] not in colon_seps):
             return result_drive + sep + result_path
         return result_drive + result_root + result_path
     except (TypeError, AttributeError, BytesWarning):
@@ -279,7 +279,7 @@ def isjunction(path):
             st = os.lstat(path)
         except (OSError, ValueError, AttributeError):
             return False
-        return bool(st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)
+        return st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT
 else:
     # Use genericpath.isjunction as imported above
     pass
@@ -340,8 +340,8 @@ def isreserved(path):
 def _isreservedname(name):
     """Return true if the filename is reserved by the system."""
     # Trailing dots and spaces are reserved.
-    if name.endswith(('.', ' ')) and name not in ('.', '..'):
-        return True
+    if name[-1:] in ('.', ' '):
+        return name not in ('.', '..')
     # Wildcards, separators, colon, and pipe (*?"<>/\:|) are reserved.
     # ASCII control characters (0-31) are reserved.
     # Colon is reserved for file streams (e.g. "name:stream[:type]").
@@ -350,9 +350,7 @@ def _isreservedname(name):
     # DOS device names are reserved (e.g. "nul" or "nul .txt"). The rules
     # are complex and vary across Windows versions. On the side of
     # caution, return True for names that may not be reserved.
-    if name.partition('.')[0].rstrip(' ').upper() in _reserved_names:
-        return True
-    return False
+    return name.partition('.')[0].rstrip(' ').upper() in _reserved_names
 
 
 # Expand paths beginning with '~' or '~user'.
@@ -381,13 +379,10 @@ def expanduser(path):
 
     if 'USERPROFILE' in os.environ:
         userhome = os.environ['USERPROFILE']
-    elif not 'HOMEPATH' in os.environ:
+    elif 'HOMEPATH' not in os.environ:
         return path
     else:
-        try:
-            drive = os.environ['HOMEDRIVE']
-        except KeyError:
-            drive = ''
+        drive = os.environ.get('HOMEDRIVE', '')
         userhome = join(drive, os.environ['HOMEPATH'])
 
     if i != 1: #~user
@@ -727,7 +722,8 @@ def realpath(path, *, strict=False):
             new_unc_prefix = b'\\\\'
             cwd = os.getcwdb()
             # bpo-38081: Special case for realpath(b'nul')
-            if normcase(path) == normcase(os.fsencode(devnull)):
+            devnull = b'nul'
+            if normcase(path) == devnull:
                 return b'\\\\.\\NUL'
         else:
             prefix = '\\\\?\\'
@@ -735,7 +731,8 @@ def realpath(path, *, strict=False):
             new_unc_prefix = '\\\\'
             cwd = os.getcwd()
             # bpo-38081: Special case for realpath('nul')
-            if normcase(path) == normcase(devnull):
+            devnull = 'nul'
+            if normcase(path) == devnull:
                 return '\\\\.\\NUL'
         had_prefix = path.startswith(prefix)
         if not had_prefix and not isabs(path):
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index 4fc02be69bd6e1..76ee721bfb5e33 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -213,15 +213,8 @@ def ismount(path):
     except (OSError, ValueError):
         return False
 
-    dev1 = s1.st_dev
-    dev2 = s2.st_dev
-    if dev1 != dev2:
-        return True     # path/.. on a different device as path
-    ino1 = s1.st_ino
-    ino2 = s2.st_ino
-    if ino1 == ino2:
-        return True     # path/.. is the same i-node as path
-    return False
+    # path/.. on a different device as path or the same i-node as path
+    return s1.st_dev != s2.st_dev or s1.st_ino == s2.st_ino
 
 
 # Expand paths beginning with '~' or '~user'.
@@ -270,7 +263,7 @@ def expanduser(path):
             return path
         name = path[1:i]
         if isinstance(name, bytes):
-            name = str(name, 'ASCII')
+            name = name.decode('ascii')
         try:
             pwent = pwd.getpwnam(name)
         except KeyError:
@@ -359,21 +352,19 @@ def normpath(path):
         path = os.fspath(path)
         if isinstance(path, bytes):
             sep = b'/'
-            empty = b''
             dot = b'.'
             dotdot = b'..'
         else:
             sep = '/'
-            empty = ''
             dot = '.'
             dotdot = '..'
-        if path == empty:
+        if not path:
             return dot
         _, initial_slashes, path = splitroot(path)
         comps = path.split(sep)
         new_comps = []
         for comp in comps:
-            if comp in (empty, dot):
+            if not comp or comp == dot:
                 continue
             if (comp != dotdot or (not initial_slashes and not new_comps) or
                  (new_comps and new_comps[-1] == dotdot)):
@@ -396,12 +387,12 @@ def normpath(path):
 def abspath(path):
     """Return an absolute path."""
     path = os.fspath(path)
-    if not isabs(path):
-        if isinstance(path, bytes):
-            cwd = os.getcwdb()
-        else:
-            cwd = os.getcwd()
-        path = join(cwd, path)
+    if isinstance(path, bytes):
+        if not path.startswith(b'/'):
+            path = join(os.getcwdb(), path)
+    else:
+        if not path.startswith('/'):
+            path = join(os.getcwd(), path)
     return normpath(path)
 
 
@@ -417,6 +408,7 @@ def realpath(filename, *, strict=False):
 
 # Join two paths, normalizing and eliminating any symbolic links
 # encountered in the second path.
+# Two leading slashes are replaced by a single slash.
 def _joinrealpath(path, rest, strict, seen):
     if isinstance(path, bytes):
         sep = b'/'
@@ -427,7 +419,7 @@ def _joinrealpath(path, rest, strict, seen):
         curdir = '.'
         pardir = '..'
 
-    if isabs(rest):
+    if rest.startswith(sep):
         rest = rest[1:]
         path = sep
 
@@ -439,10 +431,15 @@ def _joinrealpath(path, rest, strict, seen):
         if name == pardir:
             # parent dir
             if path:
-                path, name = split(path)
+                parent, name = split(path)
                 if name == pardir:
-                    path = join(path, pardir, pardir)
+                    # ../..
+                    path = join(path, pardir)
+                else:
+                    # foo/bar/.. -> foo
+                    path = parent
             else:
+                # ..
                 path = pardir
             continue
         newpath = join(path, name)
diff --git a/Misc/ACKS b/Misc/ACKS
index 03e458d170d2b8..fe014a364dd82d 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -191,6 +191,7 @@ Finn Bock
 Paul Boddie
 Matthew Boedicker
 Robin Boerdijk
+Wannes Boeykens
 Andra Bogildea
 Matt Bogosian
 Nikolay Bogoychev
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2024-03-29-15-04-13.gh-issue-117349.OB9kQQ.rst b/Misc/NEWS.d/next/Core 
and Builtins/2024-03-29-15-04-13.gh-issue-117349.OB9kQQ.rst
new file mode 100644
index 00000000000000..7a7bc689002017
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2024-03-29-15-04-13.gh-issue-117349.OB9kQQ.rst 
@@ -0,0 +1 @@
+Optimise several functions in :mod:`os.path`.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to