[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[OpenTAL-checkins] opental/OpenTAL/Static Directory.py path.py Py_...
From: |
Fernando Lalo Martins |
Subject: |
[OpenTAL-checkins] opental/OpenTAL/Static Directory.py path.py Py_... |
Date: |
Tue, 04 Feb 2003 21:49:35 -0500 |
CVSROOT: /cvsroot/opental
Module name: opental
Changes by: Fernando Lalo Martins <address@hidden> 03/02/04 21:49:35
Modified files:
OpenTAL/Static : Directory.py path.py
Added files:
OpenTAL/Static : Py_File.py TAL_File.py __init__.py sample.tal
Log message:
Static is now pretty much usable from python; next TODO item is write
the command line interface
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/OpenTAL/Static/Py_File.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/OpenTAL/Static/TAL_File.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/OpenTAL/Static/__init__.py?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/OpenTAL/Static/sample.tal?rev=1.1
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/OpenTAL/Static/Directory.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/opental/opental/OpenTAL/Static/path.py.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
Patches:
Index: opental/OpenTAL/Static/Directory.py
diff -u opental/OpenTAL/Static/Directory.py:1.1
opental/OpenTAL/Static/Directory.py:1.2
--- opental/OpenTAL/Static/Directory.py:1.1 Thu Jan 16 17:52:46 2003
+++ opental/OpenTAL/Static/Directory.py Tue Feb 4 21:49:35 2003
@@ -16,3 +16,58 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
""" Wrap a filesystem directory as an object """
+
+from pax.backwards_compatibility import *
+from path import _base as Path_base, path as Path
+from TAL_File import TAL_File
+from Py_File import Py_File
+import os
+
+extensions = (
+ ('.tal', TAL_File),
+ ('.py', Py_File),
+ ('.pyc', Py_File),
+)
+
+class Directory(object):
+ """ Wrap a filesystem directory as an object """
+ def __init__(self, path=None):
+ if path is None:
+ path = os.getcwd()
+ if not isinstance(path, Path):
+ path = Path(path)
+ self.__path = path
+ self.__cache = {}
+
+ def __getattr__(self, name):
+ if not self.__cache.has_key(name):
+ path = self.__path / name
+ if path.isdir():
+ o = Directory(path)
+ elif path.isfile():
+ for ext, reader in extensions:
+ if path.endswith(ext):
+ o = reader(name, path, self)
+ break
+ else:
+ o = path.text()
+ else:
+ for ext, reader in extensions:
+ epath = path + ext
+ if epath.isfile():
+ o = reader(name, epath, self)
+ break
+ else:
+ # file *REALLY* does not exist. Perhaps it is a listing
mask?
+ l = self.__path.listdir(name)
+ if l:
+ return [getattr(self, p.name) for p in l]
+ raise AttributeError, name
+ self.__cache[name] = o
+ return self.__cache[name]
+
+ def _ls(self, pattern):
+ return [getattr(self, p.name) for p in self.__path.listdir(pattern)]
+
+ def __repr__(self):
+ return 'Directory(%s)' % Path_base.__repr__(self.__path)
Index: opental/OpenTAL/Static/path.py
diff -u opental/OpenTAL/Static/path.py:1.1 opental/OpenTAL/Static/path.py:1.2
--- opental/OpenTAL/Static/path.py:1.1 Thu Jan 30 17:26:44 2003
+++ opental/OpenTAL/Static/path.py Tue Feb 4 21:49:35 2003
@@ -1,26 +1,41 @@
""" path.py - An object representing a path to a file or directory.
-Copyright (C) 2002 Jason Orendorff <address@hidden>
-http://www.jorendorff.com/articles/python/path/
-
Example:
from path import path
-f = path('/usr/home/guido/bin')
-for script in f:
- if script.isfile() and script.ext == '.py':
- os.chmod(script, 0755)
+d = path('/usr/home/guido/bin')
+for f in d.files():
+ if f.ext == '.py':
+ f.chmod(0755)
+
+This module requires Python 2.2 or later.
+
+URL: http://www.jorendorff.com/articles/python/path
+Author: Jason Orendorff <address@hidden> (and others - see the url!)
+Date: 1 Feb 2003
"""
+
+# TODO
+# - Is __iter__ worth the trouble? It breaks the sequence
+# protocol and breaks compatibility with str/unicode.
+# - Perhaps support arguments to touch().
+# - Note: __add__() technically has a bug, I think, where
+# it doesn't play nice with other types that implement
+# __radd__(). Test this.
+# - Better error message in listdir() when not self.isdir().
+# (On Windows, the error message really sucks.)
+# - Make sure everything has a good docstring.
+
from __future__ import generators
-import os
+import sys, os, glob, fnmatch, shutil, codecs
-__version__ = '1.0.2'
+__version__ = '1.1.2'
__all__ = ['path']
-# The try block is only needed for pre-2.3 support.
+# Pre-2.3 support. Are unicode filenames supported?
_base = str
try:
if os.path.supports_unicode_filenames:
@@ -28,12 +43,18 @@
except AttributeError:
pass
-# Pre-2.3 support for basestring.
+# Pre-2.3 workaround for basestring.
try:
basestring
except NameError:
basestring = (str, unicode)
+# Universal newline support
+_textmode = 'r'
+if hasattr(file, 'newlines'):
+ _textmode = 'U'
+
+
class path(_base):
""" Represents a filesystem path.
@@ -41,8 +62,7 @@
counterparts in os.path.
"""
- def __init__(self, path):
- str.__init__(self, path)
+ # --- Special Python methods.
def __repr__(self):
return 'path(%s)' % _base.__repr__(self)
@@ -52,18 +72,10 @@
# Adding a path and a string yields a path.
def __add__(self, more):
- base_result = _base.__add__(self, more)
- if base_result is NotImplemented:
- return base_result
- else:
- return path(base_result)
+ return path(_base(self) + more)
def __radd__(self, other):
- base_result = _base.__radd__(self, other)
- if base_result is NotImplemented:
- return base_result
- else:
- return path(base_result)
+ return path(other + _base(self))
# The / operator joins paths.
def __div__(self, rel):
@@ -74,40 +86,51 @@
"""
return path(os.path.join(self, rel))
- def listdir(self):
- return [self / child for child in os.listdir(self)]
+ # Make the / operator work even when true division is enabled.
+ __truediv__ = __div__
- def exists(self): return os.path.exists(self)
- def isabs(self): return os.path.isabs(self)
- def isdir(self): return os.path.isdir(self)
- def isfile(self): return os.path.isfile(self)
- def islink(self): return os.path.islink(self)
- def ismount(self): return os.path.ismount(self)
-
- def getatime(self): return os.path.getatime(self)
- def getmtime(self): return os.path.getmtime(self)
- def getctime(self): return os.path.getctime(self)
- def getsize(self): return os.path.getsize(self)
+
+ # --- Operations on path strings.
def abspath(self): return path(os.path.abspath(self))
def normcase(self): return path(os.path.normcase(self))
def normpath(self): return path(os.path.normpath(self))
def realpath(self): return path(os.path.realpath(self))
+ def expanduser(self): return path(os.path.expanduser(self))
+ def expandvars(self): return path(os.path.expandvars(self))
+ def dirname(self): return path(os.path.dirname(self))
+ basename = os.path.basename
+
+ def expand(self):
+ """ Clean up a filename by calling expandvars(),
+ expanduser(), and normpath() on it.
+
+ This is commonly everything needed to clean up a filename
+ read from a configuration file, for example.
+ """
+ return self.expandvars().expanduser().normpath()
- def dirname(self): return path(os.path.dirname(self))
- def basename(self): return os.path.basename(self)
- def getext(self):
+ def _get_ext(self):
f, ext = os.path.splitext(_base(self))
return ext
+ def _get_drive(self):
+ drive, r = os.path.splitdrive(self)
+ return path(drive)
+
parent = property(dirname)
name = property(basename)
- ext = property(getext, None, None,
- """ The file extension, for example '.py'. """)
+ ext = property(
+ _get_ext, None, None,
+ """ The file extension, for example '.py'. """)
+ drive = property(
+ _get_drive, None, None,
+ """ The drive specifier, for example 'C:'.
+ This is always empty on systems that don't use drive specifiers. """)
- def splitpath(self, *args):
- """ Return (fp.parent, fp.name). """
+ def splitpath(self):
+ """ p.splitpath() -> Return (p.parent, p.name). """
parent, child = os.path.split(self)
return path(parent), child
@@ -123,9 +146,19 @@
filename, ext = os.path.splitext(_base(self))
return path(filename), ext
- def splitunc(self):
- unc, rest = os.path.splitunc(self)
- return path(unc), rest
+ if hasattr(os.path, 'splitunc'):
+ def splitunc(self):
+ unc, rest = os.path.splitunc(self)
+ return path(unc), rest
+
+ def _get_uncshare(self):
+ unc, r = os.path.splitunc(self)
+ return path(unc)
+
+ uncshare = property(
+ _get_uncshare, None, None,
+ """ The UNC mount point for this path.
+ This is empty for paths on local drives. """)
def joinpath(self, *args):
""" Join two or more path components, adding a separator
@@ -134,6 +167,152 @@
"""
return path(os.path.join(self, *args))
+ def splitall(self):
+ """ Return a list of the path components in this path.
+
+ The first item in the list will be a path. Its value will be
+ either os.curdir, os.pardir, empty, or the root directory of
+ this path (for example, '/' or 'C:\\'). The other items in
+ the list will be strings.
+
+ path.path.joinpath(*result) will yield the original path.
+ """
+ parts = []
+ loc = self
+ while loc != os.curdir and loc != os.pardir:
+ prev = loc
+ loc, child = prev.splitpath()
+ if loc == prev:
+ break
+ parts.append(child)
+ parts.append(loc)
+ parts.reverse()
+ return parts
+
+ def relpath(self):
+ """ Return this path as a relative path,
+ based from the current working directory.
+ """
+ cwd = path(os.getcwd())
+ return cwd.relpathto(self)
+
+ def relpathto(self, dest):
+ """ Return a relative path to dest from here.
+
+ If there is no relative path from self to dest, for example if
+ they reside on different drives in Windows, then this returns
+ dest.abspath().
+ """
+ origin = self.abspath()
+ dest = path(dest).abspath()
+
+ orig_list = origin.normcase().splitall()
+ # Don't normcase dest! We want to preserve the case.
+ dest_list = dest.splitall()
+
+ if orig_list[0] != os.path.normcase(dest_list[0]):
+ # Can't get here from there.
+ return dest
+
+ # Find the location where the two paths start to differ.
+ i = 0
+ for start_seg, dest_seg in zip(orig_list, dest_list):
+ if start_seg != os.path.normcase(dest_seg):
+ break
+ i += 1
+
+ # Now i is the point where the two paths diverge.
+ # Need a certain number of "os.pardir"s to work up
+ # from the origin to the point of divergence.
+ segments = [os.pardir] * (len(orig_list) - i)
+ # Need to add the diverging part of dest_list.
+ segments += dest_list[i:]
+ if len(segments) == 0:
+ # If they happen to be identical, use os.curdir.
+ return path(os.curdir)
+ else:
+ return path(os.path.join(*segments))
+
+
+ # --- Methods for querying the filesystem.
+
+ if hasattr(os, 'access'):
+ def access(self, mode):
+ """ Return true if current user has access to this path.
+
+ mode - One of the constants os.F_OK, os.R_OK, os.W_OK, os.X_OK
+ """
+ return os.access(self, mode)
+
+ def stat(self):
+ """ Perform a stat() system call on this path. """
+ return os.stat(self)
+
+ def lstat(self):
+ """ Like path.stat(), but do not follow symbolic links. """
+ return os.lstat(self)
+
+ if hasattr(os, 'statvfs'):
+ def statvfs(self):
+ """ Perform a statvfs() system call on this path. """
+ return os.statvfs(self)
+
+ exists = os.path.exists
+ isabs = os.path.isabs
+ isdir = os.path.isdir
+ isfile = os.path.isfile
+ islink = os.path.islink
+ ismount = os.path.ismount
+
+ if hasattr(os.path, 'samefile'):
+ samefile = os.path.samefile
+
+ getatime = os.path.getatime
+ getmtime = os.path.getmtime
+ if hasattr(os.path, 'getctime'):
+ getctime = os.path.getctime
+ getsize = os.path.getsize
+
+ if hasattr(os, 'pathconf'):
+ def pathconf(self, name):
+ return os.pathconf(self, name)
+
+
+ # --- Modifying operations on files and directories
+
+ def utime(self, times):
+ """ Set the access and modified times of this file. """
+ os.utime(self, times)
+
+ def chmod(self, mode):
+ os.chmod(self, mode)
+
+ if hasattr(os, 'chown'):
+ def chown(self, uid, gid):
+ os.chown(self, uid, gid)
+
+ def rename(self, new):
+ os.rename(self, new)
+
+ def renames(self, new):
+ os.renames(self, new)
+
+
+ # --- Read-only operations on directories.
+
+ def listdir(self, pattern=None):
+ if pattern is None:
+ return [self / child for child in os.listdir(self)]
+ else:
+ return [self / child for child in os.listdir(self)
+ if fnmatch.fnmatch(child, pattern)]
+
+ def dirs(self):
+ return [p for p in self if p.isdir()]
+
+ def files(self):
+ return [p for p in self if p.isfile()]
+
def walk(self):
""" D.walk() -> iterator over files and subdirs, recursively.
@@ -157,3 +336,135 @@
yield child
for subsubdir in child.walkdirs():
yield subsubdir
+
+ def glob(self, pattern):
+ """ Return a list of path objects that match the pattern.
+
+ pattern - a path relative to this directory, with wildcards.
+
+ For example, path(os.getcwd()).glob('*.py') returns a list
+ of the Python files in the current directory.
+ """
+ return [path(name) for name in glob.glob(_base(self / pattern))]
+
+
+ # --- Create/delete operations on directories
+
+ def mkdir(self):
+ os.mkdir(self)
+
+ def makedirs(self):
+ os.makedirs(self)
+
+ def rmdir(self):
+ os.rmdir(self)
+
+ def removedirs(self):
+ os.removedirs(self)
+
+
+ # --- Read-only operations on files.
+
+ def bytes(self):
+ """ Open this file, read all bytes, return them as a string. """
+ f = file(self, 'rb')
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+ def text(self, encoding=None, errors='strict'):
+ """ Open this file, read it in, return the content as a string.
+
+ This uses 'U' mode in Python 2.3 and later.
+ """
+ f = file(self, _textmode)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+ def lines(self, encoding=None, errors='strict'):
+ """ Open this file, read all lines, return them in a list.
+
+ This uses 'U' mode in Python 2.3 and later.
+ """
+ f = file(self, _textmode)
+ try:
+ return f.readlines()
+ finally:
+ f.close()
+
+
+ # --- Modifying file operations
+
+ def touch(self):
+ """ Set the access/modified times of this file to the current time.
+ Create the file if it does not exist.
+ """
+ fd = os.open(self, os.O_WRONLY | os.O_CREAT, 0666)
+ os.close(fd)
+ os.utime(self, None)
+
+ def remove(self):
+ os.remove(self)
+
+ def unlink(self):
+ os.unlink(self)
+
+
+ # --- Links
+
+ if hasattr(os, 'link'):
+ def link(self, newpath):
+ """ Create a hard link at 'newpath', pointing to this file. """
+ os.link(self, newpath)
+
+ if hasattr(os, 'symlink'):
+ def symlink(self, newlink):
+ """ Create a symbolic link at 'newlink', pointing here. """
+ os.symlink(self, newlink)
+
+ if hasattr(os, 'readlink'):
+ def readlink(self):
+ """ Return the path to which this symbolic link points.
+
+ The result may be an absolute or a relative path.
+ """
+ return path(os.readlink(self))
+
+ def readlinkabs(self):
+ """ Return the path to which this symbolic link points.
+
+ The result is always an absolute path.
+ """
+ p = self.readlink()
+ if p.isabs():
+ return p
+ else:
+ return (self.parent / p).abspath()
+
+
+ # --- High-level functions from shutil
+
+ copyfile = shutil.copyfile
+ copymode = shutil.copymode
+ copystat = shutil.copystat
+ copy = shutil.copy
+ copy2 = shutil.copy2
+ copytree = shutil.copytree
+ if hasattr(shutil, 'move'):
+ move = shutil.move
+ rmtree = shutil.rmtree
+
+
+ # --- Special stuff from os
+
+ if hasattr(os, 'chroot'):
+ def chroot(self):
+ os.chroot(self)
+
+ if hasattr(os, 'startfile'):
+ def startfile(self):
+ os.startfile(self)
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [OpenTAL-checkins] opental/OpenTAL/Static Directory.py path.py Py_...,
Fernando Lalo Martins <=