opental-checkins
[Top][All Lists]
Advanced

[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)
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]