commit:     51c0a2f8a1b3c3d6e9081b3622d3c8870cf2673e
Author:     Brian Harring <ferringb <AT> gmail <DOT> com>
AuthorDate: Sun Nov 30 21:00:10 2025 +0000
Commit:     Brian Harring <ferringb <AT> gmail <DOT> com>
CommitDate: Sun Nov 30 21:25:18 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/snakeoil.git/commit/?id=51c0a2f8

chore: deprecate and partially delete .osutils

Signed-off-by: Brian Harring <ferringb <AT> gmail.com>

 src/snakeoil/osutils/__init__.py       | 110 +++++++++++++++++++++------------
 src/snakeoil/osutils/native_readdir.py | 104 -------------------------------
 tests/test_osutils.py                  |  39 +++---------
 3 files changed, 80 insertions(+), 173 deletions(-)

diff --git a/src/snakeoil/osutils/__init__.py b/src/snakeoil/osutils/__init__.py
index 9548974..bb7fc68 100644
--- a/src/snakeoil/osutils/__init__.py
+++ b/src/snakeoil/osutils/__init__.py
@@ -1,36 +1,5 @@
 """
 OS related functionality
-
-This module is primarily optimized implementations of various filesystem 
operations,
-written for posix specifically.  If this is a non-posix system (or extensions 
were
-disabled) it falls back to native python implementations that yield no real 
speed gains.
-
-A rough example of the performance benefits, collected from a core2 2.4GHz 
running
-python 2.6.5, w/ an EXT4 FS on a 160GB x25-M for the FS related invocations 
(it's worth
-noting the IO is pretty fast in this setup- for slow IO like nfs, the speedup 
for extension
-vs native for listdir* functionality is a fair bit larger).
-
-Rough stats:
-
-========================================================  =========   
===============
-python -m timeit code snippet                             native      
extension time
-========================================================  =========   
===============
-join("/usr/portage", "dev-util", "bsdiff", "ChangeLog")   2.8 usec    0.36 usec
-normpath("/usr/portage/foon/blah/dar")                    5.52 usec   0.15 usec
-normpath("/usr/portage//foon/blah//dar")                  5.66 usec   0.15 usec
-normpath("/usr/portage/./foon/../blah/")                  5.92 usec   0.15 usec
-listdir_files("/usr/lib64") # 2338 entries, 990 syms      18.6 msec   4.17 msec
-listdir_files("/usr/lib64", False) # same dir content     16.9 msec   1.48 msec
-readfile("/etc/passwd") # 1899 bytes                      20.4 usec   4.05 usec
-readfile("tmp-file") # 1MB                                300 usec    259 usec
-list(readlines("/etc/passwd")) # 1899 bytes, 34 lines     37.3 usec   12.8 usec
-list(readlines("/etc/passwd", False)) # leave whitespace  26.7 usec   12.8 usec
-========================================================  =========   
===============
-
-If you're just invoking join or normpath, or reading a file or two a couple of 
times,
-these optimizations are probably overkill.  If you're doing lots of path 
manipulation,
-reading files, scanning directories, etc, these optimizations start adding up
-pretty quickly.
 """
 
 __all__ = (
@@ -42,7 +11,6 @@ __all__ = (
     "listdir_files",
     "listdir_dirs",
     "listdir",
-    "readdir",
     "normpath",
     "unlink_if_exists",
     "supported_systems",
@@ -52,15 +20,16 @@ import errno
 import os
 import stat
 import sys
+from stat import (
+    S_ISDIR,
+    S_ISREG,
+)
 
-from . import native_readdir as module
-
-listdir = os.listdir
-listdir_dirs = module.listdir_dirs
-listdir_files = module.listdir_files
-readdir = module.readdir
+from snakeoil.deprecation import deprecated
 
-del module
+listdir = deprecated("snakeoil.osutils.listdir is deprecated.  Use 
os.listdir")(
+    lambda *a, **kw: os.listdir(*a, **kw)
+)
 
 
 def supported_systems(*systems):
@@ -206,6 +175,7 @@ def ensure_dirs(path, gid=-1, uid=-1, mode=0o777, 
minimal=True):
     return True
 
 
+@deprecated("snakeoil.osutils.absyymlink is deprecated")
 def abssymlink(path):
     """Return the absolute path of a symlink
 
@@ -237,6 +207,7 @@ def force_symlink(target, link):
             raise
 
 
+@deprecated("snakeoil.osutils.abspath is deprecated.  Us os.path.abspath")
 def abspath(path):
     """resolve a path absolutely, including symlink resolving.
 
@@ -257,6 +228,7 @@ def abspath(path):
         return path
 
 
+@deprecated("snakeoil.osutils.norpath is deprecated.  Us os.path.normpath")
 def normpath(mypath: str) -> str:
     """normalize path- //usr/bin becomes /usr/bin, /usr/../bin becomes /bin
 
@@ -271,7 +243,12 @@ def normpath(mypath: str) -> str:
 
 
 # convenience.  importing join into a namespace is ugly, pjoin less so
-pjoin = join = os.path.join
+pjoin = deprecated("snakeoil.osutils.pjoin is deprecated.  Use os.path.join")(
+    lambda *a, **kw: os.path.join(*a, **kw)
+)
+join = deprecated("snakeoil.osutils.join is deprecated.  Use os.path.join")(
+    lambda *a, **kw: os.path.join(*a, **kw)
+)
 
 
 def unlink_if_exists(path):
@@ -311,3 +288,56 @@ def lstat_mtime_long(path, st=None):
 
 def fstat_mtime_long(fd, st=None):
     return (os.fstat(fd) if st is None else st)[stat.ST_MTIME]
+
+
+def _stat_swallow_enoent(path, check, default=False, stat=os.stat):
+    try:
+        return check(stat(path).st_mode)
+    except OSError as oe:
+        if oe.errno == errno.ENOENT:
+            return default
+        raise
+
+
+def listdir_dirs(path, followSymlinks=True):
+    """
+    Return a list of all subdirectories within a directory
+
+    :param path: directory to scan
+    :param followSymlinks: this controls if symlinks are resolved.
+        If True and the symlink resolves to a directory, it is returned,
+        else if False it isn't returned.
+    :return: list of directories within `path`
+    """
+    scheck = S_ISDIR
+    lstat = os.lstat
+    if followSymlinks:
+        return [
+            x
+            for x in os.listdir(path)
+            if _stat_swallow_enoent(os.path.join(path, x), scheck)
+        ]
+    lstat = os.lstat
+    return [x for x in os.listdir(path) if scheck(lstat(os.path.join(path, 
x)).st_mode)]
+
+
+def listdir_files(path, followSymlinks=True):
+    """
+    Return a list of all files within a directory
+
+    :param path: directory to scan
+    :param followSymlinks: this controls if symlinks are resolved.
+        If True and the symlink resolves to a file, it is returned,
+        else if False it isn't returned.
+    :return: list of files within `path`
+    """
+
+    scheck = S_ISREG
+    if followSymlinks:
+        return [
+            x
+            for x in os.listdir(path)
+            if _stat_swallow_enoent(os.path.join(path, x), scheck)
+        ]
+    lstat = os.lstat
+    return [x for x in os.listdir(path) if scheck(lstat(os.path.join(path, 
x)).st_mode)]

diff --git a/src/snakeoil/osutils/native_readdir.py 
b/src/snakeoil/osutils/native_readdir.py
deleted file mode 100644
index d13e1ae..0000000
--- a/src/snakeoil/osutils/native_readdir.py
+++ /dev/null
@@ -1,104 +0,0 @@
-"""Wrapper for readdir which grabs file type from d_type."""
-
-import errno
-import os
-from stat import (
-    S_IFBLK,
-    S_IFCHR,
-    S_IFDIR,
-    S_IFIFO,
-    S_IFLNK,
-    S_IFMT,
-    S_IFREG,
-    S_IFSOCK,
-    S_ISDIR,
-    S_ISREG,
-)
-
-from ..mappings import ProtectedDict
-
-# we can still use the cpy pjoin here, just need to do something about the
-# import cycle.
-pjoin = os.path.join
-
-
-def stat_swallow_enoent(path, check, default=False, stat=os.stat):
-    try:
-        return check(stat(path).st_mode)
-    except OSError as oe:
-        if oe.errno == errno.ENOENT:
-            return default
-        raise
-
-
-def listdir_dirs(path, followSymlinks=True):
-    """
-    Return a list of all subdirectories within a directory
-
-    :param path: directory to scan
-    :param followSymlinks: this controls if symlinks are resolved.
-        If True and the symlink resolves to a directory, it is returned,
-        else if False it isn't returned.
-    :return: list of directories within `path`
-    """
-    scheck = S_ISDIR
-    pjf = pjoin
-    lstat = os.lstat
-    if followSymlinks:
-        return [
-            x for x in os.listdir(path) if stat_swallow_enoent(pjf(path, x), 
scheck)
-        ]
-    lstat = os.lstat
-    return [x for x in os.listdir(path) if scheck(lstat(pjf(path, x)).st_mode)]
-
-
-def listdir_files(path, followSymlinks=True):
-    """
-    Return a list of all files within a directory
-
-    :param path: directory to scan
-    :param followSymlinks: this controls if symlinks are resolved.
-        If True and the symlink resolves to a file, it is returned,
-        else if False it isn't returned.
-    :return: list of files within `path`
-    """
-
-    scheck = S_ISREG
-    pjf = pjoin
-    if followSymlinks:
-        return [
-            x for x in os.listdir(path) if stat_swallow_enoent(pjf(path, x), 
scheck)
-        ]
-    lstat = os.lstat
-    return [x for x in os.listdir(path) if scheck(lstat(pjf(path, x)).st_mode)]
-
-
-# we store this outside the function to ensure that
-# the strings used are reused, thus avoiding unneeded
-# allocations
-d_type_mapping = ProtectedDict(
-    {
-        S_IFREG: "file",
-        S_IFDIR: "directory",
-        S_IFLNK: "symlink",
-        S_IFCHR: "chardev",
-        S_IFBLK: "block",
-        S_IFSOCK: "socket",
-        S_IFIFO: "fifo",
-    }
-)
-
-
-def readdir(path):
-    """
-    Given a directory, return a list of (filename, filetype)
-
-    see :py:data:`d_type_mappings` for the translation used
-
-    :param path: path of a directory to scan
-    :return: list of (filename, filetype)
-    """
-    return [
-        (name, d_type_mapping[S_IFMT(os.lstat(pjoin(path, name)).st_mode)])
-        for name in os.listdir(path)
-    ]

diff --git a/tests/test_osutils.py b/tests/test_osutils.py
index a164d7e..7cd6162 100644
--- a/tests/test_osutils.py
+++ b/tests/test_osutils.py
@@ -11,7 +11,8 @@ import pytest
 
 from snakeoil import osutils
 from snakeoil.contexts import Namespace
-from snakeoil.osutils import native_readdir, sizeof_fmt, supported_systems
+from snakeoil.deprecation import suppress_deprecations
+from snakeoil.osutils import listdir_dirs, listdir_files, sizeof_fmt, 
supported_systems
 from snakeoil.osutils.mount import MNT_DETACH, MS_BIND, mount, umount
 
 
@@ -30,46 +31,25 @@ class ReaddirCommon:
 
 class TestNativeListDir(ReaddirCommon):
     def test_listdir_dirs(self, tmp_path, subdir):
-        assert native_readdir.listdir_dirs(tmp_path) == ["dir"]
-        assert native_readdir.listdir_dirs(subdir) == []
+        assert listdir_dirs(tmp_path) == ["dir"]
+        assert listdir_dirs(subdir) == []
 
     def test_listdir_files(self, tmp_path, subdir):
-        assert native_readdir.listdir_files(tmp_path) == ["file"]
-        assert native_readdir.listdir_dirs(subdir) == []
+        assert listdir_files(tmp_path) == ["file"]
+        assert listdir_dirs(subdir) == []
 
     def test_missing(self, tmp_path, subdir):
         return self._test_missing(
             tmp_path,
             (
-                native_readdir.listdir_dirs,
-                native_readdir.listdir_files,
+                listdir_dirs,
+                listdir_files,
             ),
         )
 
     def test_dangling_sym(self, tmp_path, subdir):
         (tmp_path / "monkeys").symlink_to("foon")
-        assert native_readdir.listdir_files(tmp_path) == ["file"]
-
-
-class TestNativeReaddir(ReaddirCommon):
-    # TODO: test char/block devices and sockets, devices might be a bit hard
-    # because it seems like you need to be root to create them in linux
-
-    def test_readdir(self, tmp_path, subdir):
-        (tmp_path / "monkeys").symlink_to("foon")
-        (tmp_path / "sym").symlink_to(tmp_path / "file")
-        expected = {
-            ("dir", "directory"),
-            ("file", "file"),
-            ("fifo", "fifo"),
-            ("monkeys", "symlink"),
-            ("sym", "symlink"),
-        }
-        assert set(native_readdir.readdir(tmp_path)) == expected
-        assert native_readdir.readdir(subdir) == []
-
-    def test_missing(self, tmp_path):
-        return self._test_missing(tmp_path, (native_readdir.readdir,))
+        assert listdir_files(tmp_path) == ["file"]
 
 
 class TestEnsureDirs:
@@ -200,6 +180,7 @@ class TestEnsureDirs:
 
 
 class TestAbsSymlink:
+    @suppress_deprecations
     def test_abssymlink(self, tmp_path):
         target = tmp_path / "target"
         linkname = tmp_path / "link"

Reply via email to