]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117349: Micro-optimize a few `os.path` functions (#117350)
authorNice Zombies <nineteendo19d0@gmail.com>
Tue, 2 Apr 2024 20:32:35 +0000 (22:32 +0200)
committerGitHub <noreply@github.com>
Tue, 2 Apr 2024 20:32:35 +0000 (21:32 +0100)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Barney Gale <barney.gale@gmail.com>
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Lib/ntpath.py
Lib/posixpath.py
Misc/ACKS
Misc/NEWS.d/next/Core and Builtins/2024-03-29-15-04-13.gh-issue-117349.OB9kQQ.rst [new file with mode: 0644]

index ecfc7d48dbb1928eae159dcc47bdc8c5f2d99897..0650f14f89f10b183a3f56ec6c903cd909812a04 100644 (file)
@@ -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 @@ if hasattr(os.stat_result, 'st_reparse_tag'):
             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 @@ else:
             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 @@ else:
             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):
index 4fc02be69bd6e1371c709314085d967066da75be..76ee721bfb5e33916071e2c4a1c3af983ed9adc8 100644 (file)
@@ -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 @@ except ImportError:
         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 @@ else:
 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 @@ symbolic links encountered in the path."""
 
 # 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)
index 03e458d170d2b83c5ad8fb034102f41816d532b6..fe014a364dd82da85ebacd4214b3ac336f3886ee 100644 (file)
--- 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 (file)
index 0000000..7a7bc68
--- /dev/null
@@ -0,0 +1 @@
+Optimise several functions in :mod:`os.path`.