snakeoil.osutils package¶
Submodules¶
Module contents¶
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.
- snakeoil.osutils.abspath(path)[source]¶
resolve a path absolutely, including symlink resolving.
Note that if it’s a symlink and the target doesn’t exist, it’ll still return the target.
- Parameters:
path – filepath to resolve.
- Raises:
EnvironmentError – some errno other than an ENOENT or EINVAL is encountered
- Returns:
the absolute path calculated against the filesystem
- snakeoil.osutils.abssymlink(path)[source]¶
Return the absolute path of a symlink
- Parameters:
path – filepath to resolve
- Returns:
resolved path
- Raises:
EnvironmentError – with errno=ENINVAL if the requested path isn’t a symlink
- snakeoil.osutils.ensure_dirs(path, gid=-1, uid=-1, mode=511, minimal=True)[source]¶
ensure dirs exist, creating as needed with (optional) gid, uid, and mode.
Be forewarned- if mode is specified to a mode that blocks the euid from accessing the dir, this code will try to create the dir.
- Parameters:
path – directory to ensure exists on disk
gid – a valid GID to set any created directories to
uid – a valid UID to set any created directories to
mode – permissions to set any created directories to
minimal – boolean controlling whether or not the specified mode must be enforced, or is the minimal permissions necessary. For example, if mode=0755, minimal=True, and a directory exists with mode 0707, this will restore the missing group perms resulting in 757.
- Returns:
True if the directory could be created/ensured to have those permissions, False if not.
- snakeoil.osutils.join(a, *p)[source]¶
Join two or more pathname components, inserting ‘/’ as needed. If any component is an absolute path, all previous path components will be discarded. An empty last part will result in a path that ends with a separator.
- snakeoil.osutils.listdir(path=None)¶
Return a list containing the names of the files in the directory.
- path can be specified as either str, bytes, or a path-like object. If path is bytes,
the filenames returned will also be bytes; in all other circumstances the filenames returned will be str.
If path is None, uses the path=’.’. On some platforms, path may also be specified as an open file descriptor;
the file descriptor must refer to a directory. If this functionality is unavailable, using it raises NotImplementedError.
The list is in arbitrary order. It does not include the special entries ‘.’ and ‘..’ even if they are present in the directory.
- snakeoil.osutils.listdir_dirs(path, followSymlinks=True)[source]¶
Return a list of all subdirectories within a directory
- Parameters:
path – directory to scan
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.
- Returns:
list of directories within path
- snakeoil.osutils.listdir_files(path, followSymlinks=True)[source]¶
Return a list of all files within a directory
- Parameters:
path – directory to scan
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.
- Returns:
list of files within path
- snakeoil.osutils.normpath(mypath: str) str [source]¶
normalize path- //usr/bin becomes /usr/bin, /usr/../bin becomes /bin
see
os.path.normpath()
for details- this function differs from os.path.normpath only in that it’ll convert leading ‘//’ into ‘/’
- snakeoil.osutils.pjoin(a, *p)¶
Join two or more pathname components, inserting ‘/’ as needed. If any component is an absolute path, all previous path components will be discarded. An empty last part will result in a path that ends with a separator.
- snakeoil.osutils.readdir(path)[source]¶
Given a directory, return a list of (filename, filetype)
see
d_type_mappings
for the translation used- Parameters:
path – path of a directory to scan
- Returns:
list of (filename, filetype)
- snakeoil.osutils.supported_systems(*systems)[source]¶
Decorator limiting functions to specified systems.
Supported platforms are passed as string arguments. When run on any other system (determined using sys.platform), the function fails immediately with
NotImplementedError
.Example usage:
>>> from snakeoil.osutils import supported_systems >>> @supported_systems('linux', 'darwin') >>> def func(param): ... return True >>> >>> if sys.platform.startswith(('linux', 'darwin')): >>> assert func() == True
NotImplementedError
is raised on platforms that aren’t supported.>>> @supported_systems('nonexistent') >>> def func2(param): ... return False >>> >>> func2() Traceback (most recent call last): ... NotImplementedError: func2 not supported on nonexistent