https://github.com/python/cpython/commit/b3dba18eab96dc95653031863bb2a222af912f2b
commit: b3dba18eab96dc95653031863bb2a222af912f2b
branch: main
author: Barney Gale <[email protected]>
committer: barneygale <[email protected]>
date: 2024-01-08T19:31:52Z
summary:

GH-113528: Speed up pathlib ABC tests. (#113788)

- Add `__slots__` to dummy path classes.
- Return namedtuple rather than `os.stat_result` from `DummyPath.stat()`.
- Reduce maximum symlink count in `DummyPathWithSymlinks.resolve()`.

files:
M Lib/pathlib/_abc.py
M Lib/test/test_pathlib/test_pathlib_abc.py

diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index 97663b904c8915..be22ecef4d214e 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -10,9 +10,6 @@
 # Internals
 #
 
-# Maximum number of symlinks to follow in PathBase.resolve()
-_MAX_SYMLINKS = 40
-
 # Reference for Windows paths can be found at
 # https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file .
 _WIN_RESERVED_NAMES = frozenset(
@@ -500,6 +497,9 @@ class PathBase(PurePathBase):
     """
     __slots__ = ()
 
+    # Maximum number of symlinks to follow in resolve()
+    _max_symlinks = 40
+
     @classmethod
     def _unsupported(cls, method_name):
         msg = f"{cls.__name__}.{method_name}() is unsupported"
@@ -971,7 +971,7 @@ def resolve(self, strict=False):
                         # Like Linux and macOS, raise OSError(errno.ELOOP) if 
too many symlinks are
                         # encountered during resolution.
                         link_count += 1
-                        if link_count >= _MAX_SYMLINKS:
+                        if link_count >= self._max_symlinks:
                             raise OSError(ELOOP, "Too many symbolic links in 
path", str(self))
                         target, target_parts = 
next_path.readlink()._split_stack()
                         # If the symlink target is absolute (like 
'/etc/hosts'), set the current
diff --git a/Lib/test/test_pathlib/test_pathlib_abc.py 
b/Lib/test/test_pathlib/test_pathlib_abc.py
index f33d4973177fb2..b088be87141729 100644
--- a/Lib/test/test_pathlib/test_pathlib_abc.py
+++ b/Lib/test/test_pathlib/test_pathlib_abc.py
@@ -1,4 +1,4 @@
-import collections.abc
+import collections
 import io
 import os
 import errno
@@ -43,6 +43,8 @@ def test_pathmod(self):
 
 
 class DummyPurePath(PurePathBase):
+    __slots__ = ()
+
     def __eq__(self, other):
         if not isinstance(other, DummyPurePath):
             return NotImplemented
@@ -660,11 +662,18 @@ def close(self):
         super().close()
 
 
+DummyPathStatResult = collections.namedtuple(
+    'DummyPathStatResult',
+    'st_mode st_ino st_dev st_nlink st_uid st_gid st_size st_atime st_mtime 
st_ctime')
+
+
 class DummyPath(PathBase):
     """
     Simple implementation of PathBase that keeps files and directories in
     memory.
     """
+    __slots__ = ()
+
     _files = {}
     _directories = {}
     _symlinks = {}
@@ -693,7 +702,7 @@ def stat(self, *, follow_symlinks=True):
             st_mode = stat.S_IFLNK
         else:
             raise FileNotFoundError(errno.ENOENT, "Not found", str(self))
-        return os.stat_result((st_mode, hash(str(self)), 0, 0, 0, 0, 0, 0, 0, 
0))
+        return DummyPathStatResult(st_mode, hash(str(self)), 0, 0, 0, 0, 0, 0, 
0, 0)
 
     def open(self, mode='r', buffering=-1, encoding=None,
              errors=None, newline=None):
@@ -1728,6 +1737,11 @@ def test_walk_symlink_location(self):
 
 
 class DummyPathWithSymlinks(DummyPath):
+    __slots__ = ()
+
+    # Reduce symlink traversal limit to make tests run faster.
+    _max_symlinks = 20
+
     def readlink(self):
         path = str(self.parent.resolve() / self.name)
         if path in self._symlinks:

_______________________________________________
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