mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
- Move functions common to all path modules into genericpath.py and have the
OS speicifc path modules import them. - Have os2emxpath import common functions fron ntpath instead of using copies
This commit is contained in:
parent
4582d7d905
commit
7b60464ceb
6 changed files with 273 additions and 476 deletions
78
Lib/genericpath.py
Normal file
78
Lib/genericpath.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
"""
|
||||||
|
Path operations common to more than one OS
|
||||||
|
Do not use directly. The OS specific modules import the appropriate
|
||||||
|
functions from this module themselves.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
|
||||||
|
__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
|
||||||
|
'getsize', 'isdir', 'isfile']
|
||||||
|
|
||||||
|
|
||||||
|
# Does a path exist?
|
||||||
|
# This is false for dangling symbolic links on systems that support them.
|
||||||
|
def exists(path):
|
||||||
|
"""Test whether a path exists. Returns False for broken symbolic links"""
|
||||||
|
try:
|
||||||
|
st = os.stat(path)
|
||||||
|
except os.error:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# This follows symbolic links, so both islink() and isdir() can be true
|
||||||
|
# for the same path ono systems that support symlinks
|
||||||
|
def isfile(path):
|
||||||
|
"""Test whether a path is a regular file"""
|
||||||
|
try:
|
||||||
|
st = os.stat(path)
|
||||||
|
except os.error:
|
||||||
|
return False
|
||||||
|
return stat.S_ISREG(st.st_mode)
|
||||||
|
|
||||||
|
|
||||||
|
# Is a path a directory?
|
||||||
|
# This follows symbolic links, so both islink() and isdir()
|
||||||
|
# can be true for the same path on systems that support symlinks
|
||||||
|
def isdir(s):
|
||||||
|
"""Return true if the pathname refers to an existing directory."""
|
||||||
|
try:
|
||||||
|
st = os.stat(s)
|
||||||
|
except os.error:
|
||||||
|
return False
|
||||||
|
return stat.S_ISDIR(st.st_mode)
|
||||||
|
|
||||||
|
|
||||||
|
def getsize(filename):
|
||||||
|
"""Return the size of a file, reported by os.stat()."""
|
||||||
|
return os.stat(filename).st_size
|
||||||
|
|
||||||
|
|
||||||
|
def getmtime(filename):
|
||||||
|
"""Return the last modification time of a file, reported by os.stat()."""
|
||||||
|
return os.stat(filename).st_mtime
|
||||||
|
|
||||||
|
|
||||||
|
def getatime(filename):
|
||||||
|
"""Return the last access time of a file, reported by os.stat()."""
|
||||||
|
return os.stat(filename).st_atime
|
||||||
|
|
||||||
|
|
||||||
|
def getctime(filename):
|
||||||
|
"""Return the metadata change time of a file, reported by os.stat()."""
|
||||||
|
return os.stat(filename).st_ctime
|
||||||
|
|
||||||
|
|
||||||
|
# Return the longest prefix of all list elements.
|
||||||
|
def commonprefix(m):
|
||||||
|
"Given a list of pathnames, returns the longest common leading component"
|
||||||
|
if not m: return ''
|
||||||
|
s1 = min(m)
|
||||||
|
s2 = max(m)
|
||||||
|
n = min(len(s1), len(s2))
|
||||||
|
for i in xrange(n):
|
||||||
|
if s1[i] != s2[i]:
|
||||||
|
return s1[:i]
|
||||||
|
return s1[:n]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from stat import *
|
from stat import *
|
||||||
|
from genericpath import *
|
||||||
|
|
||||||
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
||||||
"basename","dirname","commonprefix","getsize","getmtime",
|
"basename","dirname","commonprefix","getsize","getmtime",
|
||||||
|
@ -101,31 +102,6 @@ def ismount(s):
|
||||||
components = split(s)
|
components = split(s)
|
||||||
return len(components) == 2 and components[1] == ''
|
return len(components) == 2 and components[1] == ''
|
||||||
|
|
||||||
def isdir(s):
|
|
||||||
"""Return true if the pathname refers to an existing directory."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
st = os.stat(s)
|
|
||||||
except os.error:
|
|
||||||
return 0
|
|
||||||
return S_ISDIR(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Get size, mtime, atime of files.
|
|
||||||
|
|
||||||
def getsize(filename):
|
|
||||||
"""Return the size of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_size
|
|
||||||
|
|
||||||
def getmtime(filename):
|
|
||||||
"""Return the last modification time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_mtime
|
|
||||||
|
|
||||||
def getatime(filename):
|
|
||||||
"""Return the last access time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_atime
|
|
||||||
|
|
||||||
|
|
||||||
def islink(s):
|
def islink(s):
|
||||||
"""Return true if the pathname refers to a symbolic link."""
|
"""Return true if the pathname refers to a symbolic link."""
|
||||||
|
|
||||||
|
@ -135,29 +111,6 @@ def islink(s):
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def isfile(s):
|
|
||||||
"""Return true if the pathname refers to an existing regular file."""
|
|
||||||
|
|
||||||
try:
|
|
||||||
st = os.stat(s)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return S_ISREG(st.st_mode)
|
|
||||||
|
|
||||||
def getctime(filename):
|
|
||||||
"""Return the creation time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_ctime
|
|
||||||
|
|
||||||
def exists(s):
|
|
||||||
"""Test whether a path exists. Returns False for broken symbolic links"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
st = os.stat(s)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
|
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
|
||||||
# case.
|
# case.
|
||||||
|
|
||||||
|
@ -170,20 +123,6 @@ def lexists(path):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Return the longest prefix of all list elements.
|
|
||||||
|
|
||||||
def commonprefix(m):
|
|
||||||
"Given a list of pathnames, returns the longest common leading component"
|
|
||||||
if not m: return ''
|
|
||||||
s1 = min(m)
|
|
||||||
s2 = max(m)
|
|
||||||
n = min(len(s1), len(s2))
|
|
||||||
for i in xrange(n):
|
|
||||||
if s1[i] != s2[i]:
|
|
||||||
return s1[:i]
|
|
||||||
return s1[:n]
|
|
||||||
|
|
||||||
|
|
||||||
def expandvars(path):
|
def expandvars(path):
|
||||||
"""Dummy to retain interface-compatibility with other operating systems."""
|
"""Dummy to retain interface-compatibility with other operating systems."""
|
||||||
return path
|
return path
|
||||||
|
|
|
@ -8,6 +8,7 @@ module as os.path.
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
import sys
|
import sys
|
||||||
|
from genericpath import *
|
||||||
|
|
||||||
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
||||||
"basename","dirname","commonprefix","getsize","getmtime",
|
"basename","dirname","commonprefix","getsize","getmtime",
|
||||||
|
@ -206,86 +207,18 @@ def dirname(p):
|
||||||
"""Returns the directory component of a pathname"""
|
"""Returns the directory component of a pathname"""
|
||||||
return split(p)[0]
|
return split(p)[0]
|
||||||
|
|
||||||
|
|
||||||
# Return the longest prefix of all list elements.
|
|
||||||
|
|
||||||
def commonprefix(m):
|
|
||||||
"Given a list of pathnames, returns the longest common leading component"
|
|
||||||
if not m: return ''
|
|
||||||
s1 = min(m)
|
|
||||||
s2 = max(m)
|
|
||||||
n = min(len(s1), len(s2))
|
|
||||||
for i in xrange(n):
|
|
||||||
if s1[i] != s2[i]:
|
|
||||||
return s1[:i]
|
|
||||||
return s1[:n]
|
|
||||||
|
|
||||||
|
|
||||||
# Get size, mtime, atime of files.
|
|
||||||
|
|
||||||
def getsize(filename):
|
|
||||||
"""Return the size of a file, reported by os.stat()"""
|
|
||||||
return os.stat(filename).st_size
|
|
||||||
|
|
||||||
def getmtime(filename):
|
|
||||||
"""Return the last modification time of a file, reported by os.stat()"""
|
|
||||||
return os.stat(filename).st_mtime
|
|
||||||
|
|
||||||
def getatime(filename):
|
|
||||||
"""Return the last access time of a file, reported by os.stat()"""
|
|
||||||
return os.stat(filename).st_atime
|
|
||||||
|
|
||||||
def getctime(filename):
|
|
||||||
"""Return the creation time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_ctime
|
|
||||||
|
|
||||||
# Is a path a symbolic link?
|
# Is a path a symbolic link?
|
||||||
# This will always return false on systems where posix.lstat doesn't exist.
|
# This will always return false on systems where posix.lstat doesn't exist.
|
||||||
|
|
||||||
def islink(path):
|
def islink(path):
|
||||||
"""Test for symbolic link. On WindowsNT/95 always returns false"""
|
"""Test for symbolic link.
|
||||||
|
On WindowsNT/95 and OS/2 always returns false
|
||||||
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# alias exists to lexists
|
||||||
# Does a path exist?
|
|
||||||
|
|
||||||
def exists(path):
|
|
||||||
"""Test whether a path exists"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
lexists = exists
|
lexists = exists
|
||||||
|
|
||||||
|
|
||||||
# Is a path a dos directory?
|
|
||||||
# This follows symbolic links, so both islink() and isdir() can be true
|
|
||||||
# for the same path.
|
|
||||||
|
|
||||||
def isdir(path):
|
|
||||||
"""Test whether a path is a directory"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return stat.S_ISDIR(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Is a path a regular file?
|
|
||||||
# This follows symbolic links, so both islink() and isdir() can be true
|
|
||||||
# for the same path.
|
|
||||||
|
|
||||||
def isfile(path):
|
|
||||||
"""Test whether a path is a regular file"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return stat.S_ISREG(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Is a path a mount point? Either a root (with or without drive letter)
|
# Is a path a mount point? Either a root (with or without drive letter)
|
||||||
# or an UNC path with at most a / or \ after the mount point.
|
# or an UNC path with at most a / or \ after the mount point.
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ module as os.path.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
|
from genericpath import *
|
||||||
|
from ntpath import (expanduser, expandvars, isabs, islink, splitdrive,
|
||||||
|
splitext, split, walk)
|
||||||
|
|
||||||
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
||||||
"basename","dirname","commonprefix","getsize","getmtime",
|
"basename","dirname","commonprefix","getsize","getmtime",
|
||||||
|
@ -36,18 +39,6 @@ def normcase(s):
|
||||||
return s.replace('\\', '/').lower()
|
return s.replace('\\', '/').lower()
|
||||||
|
|
||||||
|
|
||||||
# Return whether a path is absolute.
|
|
||||||
# Trivial in Posix, harder on the Mac or MS-DOS.
|
|
||||||
# For DOS it is absolute if it starts with a slash or backslash (current
|
|
||||||
# volume), or if a pathname after the volume letter and colon / UNC resource
|
|
||||||
# starts with a slash or backslash.
|
|
||||||
|
|
||||||
def isabs(s):
|
|
||||||
"""Test whether a path is absolute"""
|
|
||||||
s = splitdrive(s)[1]
|
|
||||||
return s != '' and s[:1] in '/\\'
|
|
||||||
|
|
||||||
|
|
||||||
# Join two (or more) paths.
|
# Join two (or more) paths.
|
||||||
|
|
||||||
def join(a, *p):
|
def join(a, *p):
|
||||||
|
@ -63,17 +54,6 @@ def join(a, *p):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
# Split a path in a drive specification (a drive letter followed by a
|
|
||||||
# colon) and the path specification.
|
|
||||||
# It is always true that drivespec + pathspec == p
|
|
||||||
def splitdrive(p):
|
|
||||||
"""Split a pathname into drive and path specifiers. Returns a 2-tuple
|
|
||||||
"(drive,path)"; either part may be empty"""
|
|
||||||
if p[1:2] == ':':
|
|
||||||
return p[0:2], p[2:]
|
|
||||||
return '', p
|
|
||||||
|
|
||||||
|
|
||||||
# Parse UNC paths
|
# Parse UNC paths
|
||||||
def splitunc(p):
|
def splitunc(p):
|
||||||
"""Split a pathname into UNC mount point and relative path specifiers.
|
"""Split a pathname into UNC mount point and relative path specifiers.
|
||||||
|
@ -103,57 +83,6 @@ def splitunc(p):
|
||||||
return '', p
|
return '', p
|
||||||
|
|
||||||
|
|
||||||
# Split a path in head (everything up to the last '/') and tail (the
|
|
||||||
# rest). After the trailing '/' is stripped, the invariant
|
|
||||||
# join(head, tail) == p holds.
|
|
||||||
# The resulting head won't end in '/' unless it is the root.
|
|
||||||
|
|
||||||
def split(p):
|
|
||||||
"""Split a pathname.
|
|
||||||
|
|
||||||
Return tuple (head, tail) where tail is everything after the final slash.
|
|
||||||
Either part may be empty."""
|
|
||||||
|
|
||||||
d, p = splitdrive(p)
|
|
||||||
# set i to index beyond p's last slash
|
|
||||||
i = len(p)
|
|
||||||
while i and p[i-1] not in '/\\':
|
|
||||||
i = i - 1
|
|
||||||
head, tail = p[:i], p[i:] # now tail has no slashes
|
|
||||||
# remove trailing slashes from head, unless it's all slashes
|
|
||||||
head2 = head
|
|
||||||
while head2 and head2[-1] in '/\\':
|
|
||||||
head2 = head2[:-1]
|
|
||||||
head = head2 or head
|
|
||||||
return d + head, tail
|
|
||||||
|
|
||||||
|
|
||||||
# Split a path in root and extension.
|
|
||||||
# The extension is everything starting at the last dot in the last
|
|
||||||
# pathname component; the root is everything before that.
|
|
||||||
# It is always true that root + ext == p.
|
|
||||||
|
|
||||||
def splitext(p):
|
|
||||||
"""Split the extension from a pathname.
|
|
||||||
|
|
||||||
Extension is everything from the last dot to the end.
|
|
||||||
Return (root, ext), either part may be empty."""
|
|
||||||
root, ext = '', ''
|
|
||||||
for c in p:
|
|
||||||
if c in ['/','\\']:
|
|
||||||
root, ext = root + ext + c, ''
|
|
||||||
elif c == '.':
|
|
||||||
if ext:
|
|
||||||
root, ext = root + ext, c
|
|
||||||
else:
|
|
||||||
ext = c
|
|
||||||
elif ext:
|
|
||||||
ext = ext + c
|
|
||||||
else:
|
|
||||||
root = root + c
|
|
||||||
return root, ext
|
|
||||||
|
|
||||||
|
|
||||||
# Return the tail (basename) part of a path.
|
# Return the tail (basename) part of a path.
|
||||||
|
|
||||||
def basename(p):
|
def basename(p):
|
||||||
|
@ -168,84 +97,12 @@ def dirname(p):
|
||||||
return split(p)[0]
|
return split(p)[0]
|
||||||
|
|
||||||
|
|
||||||
# Return the longest prefix of all list elements.
|
# alias exists to lexists
|
||||||
|
|
||||||
def commonprefix(m):
|
|
||||||
"Given a list of pathnames, returns the longest common leading component"
|
|
||||||
if not m: return ''
|
|
||||||
s1 = min(m)
|
|
||||||
s2 = max(m)
|
|
||||||
n = min(len(s1), len(s2))
|
|
||||||
for i in xrange(n):
|
|
||||||
if s1[i] != s2[i]:
|
|
||||||
return s1[:i]
|
|
||||||
return s1[:n]
|
|
||||||
|
|
||||||
|
|
||||||
# Get size, mtime, atime of files.
|
|
||||||
|
|
||||||
def getsize(filename):
|
|
||||||
"""Return the size of a file, reported by os.stat()"""
|
|
||||||
return os.stat(filename).st_size
|
|
||||||
|
|
||||||
def getmtime(filename):
|
|
||||||
"""Return the last modification time of a file, reported by os.stat()"""
|
|
||||||
return os.stat(filename).st_mtime
|
|
||||||
|
|
||||||
def getatime(filename):
|
|
||||||
"""Return the last access time of a file, reported by os.stat()"""
|
|
||||||
return os.stat(filename).st_atime
|
|
||||||
|
|
||||||
def getctime(filename):
|
|
||||||
"""Return the creation time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_ctime
|
|
||||||
|
|
||||||
# Is a path a symbolic link?
|
|
||||||
# This will always return false on systems where posix.lstat doesn't exist.
|
|
||||||
|
|
||||||
def islink(path):
|
|
||||||
"""Test for symbolic link. On OS/2 always returns false"""
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
# Does a path exist?
|
|
||||||
# This is false for dangling symbolic links.
|
|
||||||
|
|
||||||
def exists(path):
|
|
||||||
"""Test whether a path exists"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
lexists = exists
|
lexists = exists
|
||||||
|
|
||||||
|
|
||||||
# Is a path a directory?
|
# Is a path a directory?
|
||||||
|
|
||||||
def isdir(path):
|
|
||||||
"""Test whether a path is a directory"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return stat.S_ISDIR(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Is a path a regular file?
|
|
||||||
# This follows symbolic links, so both islink() and isdir() can be true
|
|
||||||
# for the same path.
|
|
||||||
|
|
||||||
def isfile(path):
|
|
||||||
"""Test whether a path is a regular file"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return stat.S_ISREG(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Is a path a mount point? Either a root (with or without drive letter)
|
# Is a path a mount point? Either a root (with or without drive letter)
|
||||||
# or an UNC path with at most a / or \ after the mount point.
|
# or an UNC path with at most a / or \ after the mount point.
|
||||||
|
|
||||||
|
@ -258,131 +115,6 @@ def ismount(path):
|
||||||
return len(p) == 1 and p[0] in '/\\'
|
return len(p) == 1 and p[0] in '/\\'
|
||||||
|
|
||||||
|
|
||||||
# Directory tree walk.
|
|
||||||
# For each directory under top (including top itself, but excluding
|
|
||||||
# '.' and '..'), func(arg, dirname, filenames) is called, where
|
|
||||||
# dirname is the name of the directory and filenames is the list
|
|
||||||
# of files (and subdirectories etc.) in the directory.
|
|
||||||
# The func may modify the filenames list, to implement a filter,
|
|
||||||
# or to impose a different order of visiting.
|
|
||||||
|
|
||||||
def walk(top, func, arg):
|
|
||||||
"""Directory tree walk whth callback function.
|
|
||||||
|
|
||||||
walk(top, func, arg) calls func(arg, d, files) for each directory d
|
|
||||||
in the tree rooted at top (including top itself); files is a list
|
|
||||||
of all the files and subdirs in directory d."""
|
|
||||||
try:
|
|
||||||
names = os.listdir(top)
|
|
||||||
except os.error:
|
|
||||||
return
|
|
||||||
func(arg, top, names)
|
|
||||||
exceptions = ('.', '..')
|
|
||||||
for name in names:
|
|
||||||
if name not in exceptions:
|
|
||||||
name = join(top, name)
|
|
||||||
if isdir(name):
|
|
||||||
walk(name, func, arg)
|
|
||||||
|
|
||||||
|
|
||||||
# Expand paths beginning with '~' or '~user'.
|
|
||||||
# '~' means $HOME; '~user' means that user's home directory.
|
|
||||||
# If the path doesn't begin with '~', or if the user or $HOME is unknown,
|
|
||||||
# the path is returned unchanged (leaving error reporting to whatever
|
|
||||||
# function is called with the expanded path as argument).
|
|
||||||
# See also module 'glob' for expansion of *, ? and [...] in pathnames.
|
|
||||||
# (A function should also be defined to do full *sh-style environment
|
|
||||||
# variable expansion.)
|
|
||||||
|
|
||||||
def expanduser(path):
|
|
||||||
"""Expand ~ and ~user constructs.
|
|
||||||
|
|
||||||
If user or $HOME is unknown, do nothing."""
|
|
||||||
if path[:1] != '~':
|
|
||||||
return path
|
|
||||||
i, n = 1, len(path)
|
|
||||||
while i < n and path[i] not in '/\\':
|
|
||||||
i = i + 1
|
|
||||||
if i == 1:
|
|
||||||
if 'HOME' in os.environ:
|
|
||||||
userhome = os.environ['HOME']
|
|
||||||
elif not 'HOMEPATH' in os.environ:
|
|
||||||
return path
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
drive = os.environ['HOMEDRIVE']
|
|
||||||
except KeyError:
|
|
||||||
drive = ''
|
|
||||||
userhome = join(drive, os.environ['HOMEPATH'])
|
|
||||||
else:
|
|
||||||
return path
|
|
||||||
return userhome + path[i:]
|
|
||||||
|
|
||||||
|
|
||||||
# Expand paths containing shell variable substitutions.
|
|
||||||
# The following rules apply:
|
|
||||||
# - no expansion within single quotes
|
|
||||||
# - no escape character, except for '$$' which is translated into '$'
|
|
||||||
# - ${varname} is accepted.
|
|
||||||
# - varnames can be made out of letters, digits and the character '_'
|
|
||||||
# XXX With COMMAND.COM you can use any characters in a variable name,
|
|
||||||
# XXX except '^|<>='.
|
|
||||||
|
|
||||||
def expandvars(path):
|
|
||||||
"""Expand shell variables of form $var and ${var}.
|
|
||||||
|
|
||||||
Unknown variables are left unchanged."""
|
|
||||||
if '$' not in path:
|
|
||||||
return path
|
|
||||||
import string
|
|
||||||
varchars = string.letters + string.digits + '_-'
|
|
||||||
res = ''
|
|
||||||
index = 0
|
|
||||||
pathlen = len(path)
|
|
||||||
while index < pathlen:
|
|
||||||
c = path[index]
|
|
||||||
if c == '\'': # no expansion within single quotes
|
|
||||||
path = path[index + 1:]
|
|
||||||
pathlen = len(path)
|
|
||||||
try:
|
|
||||||
index = path.index('\'')
|
|
||||||
res = res + '\'' + path[:index + 1]
|
|
||||||
except ValueError:
|
|
||||||
res = res + path
|
|
||||||
index = pathlen - 1
|
|
||||||
elif c == '$': # variable or '$$'
|
|
||||||
if path[index + 1:index + 2] == '$':
|
|
||||||
res = res + c
|
|
||||||
index = index + 1
|
|
||||||
elif path[index + 1:index + 2] == '{':
|
|
||||||
path = path[index+2:]
|
|
||||||
pathlen = len(path)
|
|
||||||
try:
|
|
||||||
index = path.index('}')
|
|
||||||
var = path[:index]
|
|
||||||
if var in os.environ:
|
|
||||||
res = res + os.environ[var]
|
|
||||||
except ValueError:
|
|
||||||
res = res + path
|
|
||||||
index = pathlen - 1
|
|
||||||
else:
|
|
||||||
var = ''
|
|
||||||
index = index + 1
|
|
||||||
c = path[index:index + 1]
|
|
||||||
while c != '' and c in varchars:
|
|
||||||
var = var + c
|
|
||||||
index = index + 1
|
|
||||||
c = path[index:index + 1]
|
|
||||||
if var in os.environ:
|
|
||||||
res = res + os.environ[var]
|
|
||||||
if c != '':
|
|
||||||
res = res + c
|
|
||||||
else:
|
|
||||||
res = res + c
|
|
||||||
index = index + 1
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
|
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
|
||||||
|
|
||||||
def normpath(path):
|
def normpath(path):
|
||||||
|
|
|
@ -12,6 +12,7 @@ for manipulation of the pathname component of URLs.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import stat
|
import stat
|
||||||
|
from genericpath import *
|
||||||
|
|
||||||
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
|
||||||
"basename","dirname","commonprefix","getsize","getmtime",
|
"basename","dirname","commonprefix","getsize","getmtime",
|
||||||
|
@ -119,37 +120,6 @@ def dirname(p):
|
||||||
return split(p)[0]
|
return split(p)[0]
|
||||||
|
|
||||||
|
|
||||||
# Return the longest prefix of all list elements.
|
|
||||||
|
|
||||||
def commonprefix(m):
|
|
||||||
"Given a list of pathnames, returns the longest common leading component"
|
|
||||||
if not m: return ''
|
|
||||||
s1 = min(m)
|
|
||||||
s2 = max(m)
|
|
||||||
n = min(len(s1), len(s2))
|
|
||||||
for i in xrange(n):
|
|
||||||
if s1[i] != s2[i]:
|
|
||||||
return s1[:i]
|
|
||||||
return s1[:n]
|
|
||||||
|
|
||||||
# Get size, mtime, atime of files.
|
|
||||||
|
|
||||||
def getsize(filename):
|
|
||||||
"""Return the size of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_size
|
|
||||||
|
|
||||||
def getmtime(filename):
|
|
||||||
"""Return the last modification time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_mtime
|
|
||||||
|
|
||||||
def getatime(filename):
|
|
||||||
"""Return the last access time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_atime
|
|
||||||
|
|
||||||
def getctime(filename):
|
|
||||||
"""Return the metadata change time of a file, reported by os.stat()."""
|
|
||||||
return os.stat(filename).st_ctime
|
|
||||||
|
|
||||||
# Is a path a symbolic link?
|
# Is a path a symbolic link?
|
||||||
# This will always return false on systems where os.lstat doesn't exist.
|
# This will always return false on systems where os.lstat doesn't exist.
|
||||||
|
|
||||||
|
@ -161,19 +131,6 @@ def islink(path):
|
||||||
return False
|
return False
|
||||||
return stat.S_ISLNK(st.st_mode)
|
return stat.S_ISLNK(st.st_mode)
|
||||||
|
|
||||||
|
|
||||||
# Does a path exist?
|
|
||||||
# This is false for dangling symbolic links.
|
|
||||||
|
|
||||||
def exists(path):
|
|
||||||
"""Test whether a path exists. Returns False for broken symbolic links"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
# Being true for dangling symbolic links is also useful.
|
# Being true for dangling symbolic links is also useful.
|
||||||
|
|
||||||
def lexists(path):
|
def lexists(path):
|
||||||
|
@ -185,32 +142,6 @@ def lexists(path):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
# Is a path a directory?
|
|
||||||
# This follows symbolic links, so both islink() and isdir() can be true
|
|
||||||
# for the same path.
|
|
||||||
|
|
||||||
def isdir(path):
|
|
||||||
"""Test whether a path is a directory"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return stat.S_ISDIR(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Is a path a regular file?
|
|
||||||
# This follows symbolic links, so both islink() and isfile() can be true
|
|
||||||
# for the same path.
|
|
||||||
|
|
||||||
def isfile(path):
|
|
||||||
"""Test whether a path is a regular file"""
|
|
||||||
try:
|
|
||||||
st = os.stat(path)
|
|
||||||
except os.error:
|
|
||||||
return False
|
|
||||||
return stat.S_ISREG(st.st_mode)
|
|
||||||
|
|
||||||
|
|
||||||
# Are two filenames really pointing to the same file?
|
# Are two filenames really pointing to the same file?
|
||||||
|
|
||||||
def samefile(f1, f2):
|
def samefile(f1, f2):
|
||||||
|
|
184
Lib/test/test_genericpath.py
Normal file
184
Lib/test/test_genericpath.py
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
import unittest
|
||||||
|
from test import test_support
|
||||||
|
import os
|
||||||
|
import genericpath
|
||||||
|
|
||||||
|
class AllCommonTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def assertIs(self, a, b):
|
||||||
|
self.assert_(a is b)
|
||||||
|
|
||||||
|
def test_commonprefix(self):
|
||||||
|
self.assertEqual(
|
||||||
|
genericpath.commonprefix([]),
|
||||||
|
""
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
genericpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
|
||||||
|
"/home/swen"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
genericpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
|
||||||
|
"/home/swen/"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
genericpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]),
|
||||||
|
"/home/swen/spam"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_getsize(self):
|
||||||
|
f = open(test_support.TESTFN, "wb")
|
||||||
|
try:
|
||||||
|
f.write("foo")
|
||||||
|
f.close()
|
||||||
|
self.assertEqual(genericpath.getsize(test_support.TESTFN), 3)
|
||||||
|
finally:
|
||||||
|
if not f.closed:
|
||||||
|
f.close()
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
|
||||||
|
def test_time(self):
|
||||||
|
f = open(test_support.TESTFN, "wb")
|
||||||
|
try:
|
||||||
|
f.write("foo")
|
||||||
|
f.close()
|
||||||
|
f = open(test_support.TESTFN, "ab")
|
||||||
|
f.write("bar")
|
||||||
|
f.close()
|
||||||
|
f = open(test_support.TESTFN, "rb")
|
||||||
|
d = f.read()
|
||||||
|
f.close()
|
||||||
|
self.assertEqual(d, "foobar")
|
||||||
|
|
||||||
|
self.assert_(
|
||||||
|
genericpath.getctime(test_support.TESTFN) <=
|
||||||
|
genericpath.getmtime(test_support.TESTFN)
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
if not f.closed:
|
||||||
|
f.close()
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
|
||||||
|
def test_exists(self):
|
||||||
|
self.assertIs(genericpath.exists(test_support.TESTFN), False)
|
||||||
|
f = open(test_support.TESTFN, "wb")
|
||||||
|
try:
|
||||||
|
f.write("foo")
|
||||||
|
f.close()
|
||||||
|
self.assertIs(genericpath.exists(test_support.TESTFN), True)
|
||||||
|
finally:
|
||||||
|
if not f.close():
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, genericpath.exists)
|
||||||
|
|
||||||
|
def test_isdir(self):
|
||||||
|
self.assertIs(genericpath.isdir(test_support.TESTFN), False)
|
||||||
|
f = open(test_support.TESTFN, "wb")
|
||||||
|
try:
|
||||||
|
f.write("foo")
|
||||||
|
f.close()
|
||||||
|
self.assertIs(genericpath.isdir(test_support.TESTFN), False)
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
os.mkdir(test_support.TESTFN)
|
||||||
|
self.assertIs(genericpath.isdir(test_support.TESTFN), True)
|
||||||
|
os.rmdir(test_support.TESTFN)
|
||||||
|
finally:
|
||||||
|
if not f.close():
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.rmdir(test_support.TESTFN)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, genericpath.isdir)
|
||||||
|
|
||||||
|
def test_isfile(self):
|
||||||
|
self.assertIs(genericpath.isfile(test_support.TESTFN), False)
|
||||||
|
f = open(test_support.TESTFN, "wb")
|
||||||
|
try:
|
||||||
|
f.write("foo")
|
||||||
|
f.close()
|
||||||
|
self.assertIs(genericpath.isfile(test_support.TESTFN), True)
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
os.mkdir(test_support.TESTFN)
|
||||||
|
self.assertIs(genericpath.isfile(test_support.TESTFN), False)
|
||||||
|
os.rmdir(test_support.TESTFN)
|
||||||
|
finally:
|
||||||
|
if not f.close():
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
os.remove(test_support.TESTFN)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.rmdir(test_support.TESTFN)
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, genericpath.isdir)
|
||||||
|
|
||||||
|
def test_samefile(self):
|
||||||
|
f = open(test_support.TESTFN + "1", "wb")
|
||||||
|
try:
|
||||||
|
f.write("foo")
|
||||||
|
f.close()
|
||||||
|
self.assertIs(
|
||||||
|
genericpath.samefile(
|
||||||
|
test_support.TESTFN + "1",
|
||||||
|
test_support.TESTFN + "1"
|
||||||
|
),
|
||||||
|
True
|
||||||
|
)
|
||||||
|
# If we don't have links, assume that os.stat doesn't return resonable
|
||||||
|
# inode information and thus, that samefile() doesn't work
|
||||||
|
if hasattr(os, "symlink"):
|
||||||
|
os.symlink(
|
||||||
|
test_support.TESTFN + "1",
|
||||||
|
test_support.TESTFN + "2"
|
||||||
|
)
|
||||||
|
self.assertIs(
|
||||||
|
genericpath.samefile(
|
||||||
|
test_support.TESTFN + "1",
|
||||||
|
test_support.TESTFN + "2"
|
||||||
|
),
|
||||||
|
True
|
||||||
|
)
|
||||||
|
os.remove(test_support.TESTFN + "2")
|
||||||
|
f = open(test_support.TESTFN + "2", "wb")
|
||||||
|
f.write("bar")
|
||||||
|
f.close()
|
||||||
|
self.assertIs(
|
||||||
|
genericpath.samefile(
|
||||||
|
test_support.TESTFN + "1",
|
||||||
|
test_support.TESTFN + "2"
|
||||||
|
),
|
||||||
|
False
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
if not f.close():
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
os.remove(test_support.TESTFN + "1")
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.remove(test_support.TESTFN + "2")
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, genericpath.samefile)
|
||||||
|
|
||||||
|
def test_main():
|
||||||
|
test_support.run_unittest(AllCommonTest)
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
test_main()
|
Loading…
Add table
Add a link
Reference in a new issue