/[opental]/opental/OpenTAL/Static/path.py
ViewVC logotype

Diff of /opental/OpenTAL/Static/path.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by lalo, Thu Jan 30 22:26:44 2003 UTC revision 1.2 by lalo, Wed Feb 5 02:49:35 2003 UTC
# Line 1  Line 1 
1  """ path.py - An object representing a path to a file or directory.  """ path.py - An object representing a path to a file or directory.
2    
 Copyright (C) 2002 Jason Orendorff <jason@jorendorff.com>  
 http://www.jorendorff.com/articles/python/path/  
   
3  Example:  Example:
4    
5  from path import path  from path import path
6  f = path('/usr/home/guido/bin')  d = path('/usr/home/guido/bin')
7  for script in f:  for f in d.files():
8      if script.isfile() and script.ext == '.py':      if f.ext == '.py':
9          os.chmod(script, 0755)          f.chmod(0755)
10    
11    This module requires Python 2.2 or later.
12    
13    
14    URL:     http://www.jorendorff.com/articles/python/path
15    Author:  Jason Orendorff <jason@jorendorff.com> (and others - see the url!)
16    Date:    1 Feb 2003
17  """  """
18    
19    
20    # TODO
21    #   - Is __iter__ worth the trouble?  It breaks the sequence
22    #     protocol and breaks compatibility with str/unicode.
23    #   - Perhaps support arguments to touch().
24    #   - Note:  __add__() technically has a bug, I think, where
25    #     it doesn't play nice with other types that implement
26    #     __radd__().  Test this.
27    #   - Better error message in listdir() when not self.isdir().
28    #     (On Windows, the error message really sucks.)
29    #   - Make sure everything has a good docstring.
30    
31  from __future__ import generators  from __future__ import generators
32    
33  import os  import sys, os, glob, fnmatch, shutil, codecs
34    
35  __version__ = '1.0.2'  __version__ = '1.1.2'
36  __all__ = ['path']  __all__ = ['path']
37    
38  # The try block is only needed for pre-2.3 support.  # Pre-2.3 support.  Are unicode filenames supported?
39  _base = str  _base = str
40  try:  try:
41      if os.path.supports_unicode_filenames:      if os.path.supports_unicode_filenames:
# Line 28  try: Line 43  try:
43  except AttributeError:  except AttributeError:
44      pass      pass
45    
46  # Pre-2.3 support for basestring.  # Pre-2.3 workaround for basestring.
47  try:  try:
48      basestring      basestring
49  except NameError:  except NameError:
50      basestring = (str, unicode)      basestring = (str, unicode)
51    
52    # Universal newline support
53    _textmode = 'r'
54    if hasattr(file, 'newlines'):
55        _textmode = 'U'
56    
57    
58  class path(_base):  class path(_base):
59      """ Represents a filesystem path.      """ Represents a filesystem path.
60    
# Line 41  class path(_base): Line 62  class path(_base):
62      counterparts in os.path.      counterparts in os.path.
63      """      """
64    
65      def __init__(self, path):      # --- Special Python methods.
         str.__init__(self, path)  
66    
67      def __repr__(self):      def __repr__(self):
68          return 'path(%s)' % _base.__repr__(self)          return 'path(%s)' % _base.__repr__(self)
# Line 52  class path(_base): Line 72  class path(_base):
72    
73      # Adding a path and a string yields a path.      # Adding a path and a string yields a path.
74      def __add__(self, more):      def __add__(self, more):
75          base_result = _base.__add__(self, more)          return path(_base(self) + more)
         if base_result is NotImplemented:  
             return base_result  
         else:  
             return path(base_result)  
76    
77      def __radd__(self, other):      def __radd__(self, other):
78          base_result = _base.__radd__(self, other)          return path(other + _base(self))
         if base_result is NotImplemented:  
             return base_result  
         else:  
             return path(base_result)  
79    
80      # The / operator joins paths.      # The / operator joins paths.
81      def __div__(self, rel):      def __div__(self, rel):
# Line 74  class path(_base): Line 86  class path(_base):
86          """          """
87          return path(os.path.join(self, rel))          return path(os.path.join(self, rel))
88    
89      def listdir(self):      # Make the / operator work even when true division is enabled.
90          return [self / child for child in os.listdir(self)]      __truediv__ = __div__
91    
92      def exists(self):        return os.path.exists(self)  
93      def isabs(self):         return os.path.isabs(self)      # --- Operations on path strings.
     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)  
94    
95      def abspath(self):       return path(os.path.abspath(self))      def abspath(self):       return path(os.path.abspath(self))
96      def normcase(self):      return path(os.path.normcase(self))      def normcase(self):      return path(os.path.normcase(self))
97      def normpath(self):      return path(os.path.normpath(self))      def normpath(self):      return path(os.path.normpath(self))
98      def realpath(self):      return path(os.path.realpath(self))      def realpath(self):      return path(os.path.realpath(self))
99        def expanduser(self):    return path(os.path.expanduser(self))
100        def expandvars(self):    return path(os.path.expandvars(self))
101        def dirname(self):       return path(os.path.dirname(self))
102        basename = os.path.basename
103    
104        def expand(self):
105            """ Clean up a filename by calling expandvars(),
106            expanduser(), and normpath() on it.
107    
108            This is commonly everything needed to clean up a filename
109            read from a configuration file, for example.
110            """
111            return self.expandvars().expanduser().normpath()
112    
     def dirname(self):    return path(os.path.dirname(self))  
     def basename(self):   return os.path.basename(self)  
113    
114      def getext(self):      def _get_ext(self):
115          f, ext = os.path.splitext(_base(self))          f, ext = os.path.splitext(_base(self))
116          return ext          return ext
117    
118        def _get_drive(self):
119            drive, r = os.path.splitdrive(self)
120            return path(drive)
121    
122      parent = property(dirname)      parent = property(dirname)
123      name = property(basename)      name = property(basename)
124      ext = property(getext, None, None,      ext = property(
125                     """ The file extension, for example '.py'. """)          _get_ext, None, None,
126            """ The file extension, for example '.py'. """)
127        drive = property(
128            _get_drive, None, None,
129            """ The drive specifier, for example 'C:'.
130            This is always empty on systems that don't use drive specifiers. """)
131    
132      def splitpath(self, *args):      def splitpath(self):
133          """ Return (fp.parent, fp.name). """          """ p.splitpath() -> Return (p.parent, p.name). """
134          parent, child = os.path.split(self)          parent, child = os.path.split(self)
135          return path(parent), child          return path(parent), child
136    
# Line 123  class path(_base): Line 146  class path(_base):
146          filename, ext = os.path.splitext(_base(self))          filename, ext = os.path.splitext(_base(self))
147          return path(filename), ext          return path(filename), ext
148    
149      def splitunc(self):      if hasattr(os.path, 'splitunc'):
150          unc, rest = os.path.splitunc(self)          def splitunc(self):
151          return path(unc), rest              unc, rest = os.path.splitunc(self)
152                return path(unc), rest
153    
154            def _get_uncshare(self):
155                unc, r = os.path.splitunc(self)
156                return path(unc)
157    
158            uncshare = property(
159                _get_uncshare, None, None,
160                """ The UNC mount point for this path.
161                This is empty for paths on local drives. """)
162    
163      def joinpath(self, *args):      def joinpath(self, *args):
164          """ Join two or more path components, adding a separator          """ Join two or more path components, adding a separator
# Line 134  class path(_base): Line 167  class path(_base):
167          """          """
168          return path(os.path.join(self, *args))          return path(os.path.join(self, *args))
169    
170        def splitall(self):
171            """ Return a list of the path components in this path.
172    
173            The first item in the list will be a path.  Its value will be
174            either os.curdir, os.pardir, empty, or the root directory of
175            this path (for example, '/' or 'C:\\').  The other items in
176            the list will be strings.
177    
178            path.path.joinpath(*result) will yield the original path.
179            """
180            parts = []
181            loc = self
182            while loc != os.curdir and loc != os.pardir:
183                prev = loc
184                loc, child = prev.splitpath()
185                if loc == prev:
186                    break
187                parts.append(child)
188            parts.append(loc)
189            parts.reverse()
190            return parts
191    
192        def relpath(self):
193            """ Return this path as a relative path,
194            based from the current working directory.
195            """
196            cwd = path(os.getcwd())
197            return cwd.relpathto(self)
198    
199        def relpathto(self, dest):
200            """ Return a relative path to dest from here.
201    
202            If there is no relative path from self to dest, for example if
203            they reside on different drives in Windows, then this returns
204            dest.abspath().
205            """
206            origin = self.abspath()
207            dest = path(dest).abspath()
208    
209            orig_list = origin.normcase().splitall()
210            # Don't normcase dest!  We want to preserve the case.
211            dest_list = dest.splitall()
212    
213            if orig_list[0] != os.path.normcase(dest_list[0]):
214                # Can't get here from there.
215                return dest
216    
217            # Find the location where the two paths start to differ.
218            i = 0
219            for start_seg, dest_seg in zip(orig_list, dest_list):
220                if start_seg != os.path.normcase(dest_seg):
221                    break
222                i += 1
223    
224            # Now i is the point where the two paths diverge.
225            # Need a certain number of "os.pardir"s to work up
226            # from the origin to the point of divergence.
227            segments = [os.pardir] * (len(orig_list) - i)
228            # Need to add the diverging part of dest_list.
229            segments += dest_list[i:]
230            if len(segments) == 0:
231                # If they happen to be identical, use os.curdir.
232                return path(os.curdir)
233            else:
234                return path(os.path.join(*segments))
235    
236    
237        # --- Methods for querying the filesystem.
238    
239        if hasattr(os, 'access'):
240            def access(self, mode):
241                """ Return true if current user has access to this path.
242    
243                mode - One of the constants os.F_OK, os.R_OK, os.W_OK, os.X_OK
244                """
245                return os.access(self, mode)
246    
247        def stat(self):
248            """ Perform a stat() system call on this path. """
249            return os.stat(self)
250    
251        def lstat(self):
252            """ Like path.stat(), but do not follow symbolic links. """
253            return os.lstat(self)
254    
255        if hasattr(os, 'statvfs'):
256            def statvfs(self):
257                """ Perform a statvfs() system call on this path. """
258                return os.statvfs(self)
259    
260        exists = os.path.exists
261        isabs = os.path.isabs
262        isdir = os.path.isdir
263        isfile = os.path.isfile
264        islink = os.path.islink
265        ismount = os.path.ismount
266    
267        if hasattr(os.path, 'samefile'):
268            samefile = os.path.samefile
269    
270        getatime = os.path.getatime
271        getmtime = os.path.getmtime
272        if hasattr(os.path, 'getctime'):
273            getctime = os.path.getctime
274        getsize = os.path.getsize
275    
276        if hasattr(os, 'pathconf'):
277            def pathconf(self, name):
278                return os.pathconf(self, name)
279    
280    
281        # --- Modifying operations on files and directories
282    
283        def utime(self, times):
284            """ Set the access and modified times of this file. """
285            os.utime(self, times)
286    
287        def chmod(self, mode):
288            os.chmod(self, mode)
289    
290        if hasattr(os, 'chown'):
291            def chown(self, uid, gid):
292                os.chown(self, uid, gid)
293    
294        def rename(self, new):
295            os.rename(self, new)
296    
297        def renames(self, new):
298            os.renames(self, new)
299    
300    
301        # --- Read-only operations on directories.
302    
303        def listdir(self, pattern=None):
304            if pattern is None:
305                return [self / child for child in os.listdir(self)]
306            else:
307                return [self / child for child in os.listdir(self)
308                        if fnmatch.fnmatch(child, pattern)]
309    
310        def dirs(self):
311            return [p for p in self if p.isdir()]
312    
313        def files(self):
314            return [p for p in self if p.isfile()]
315    
316      def walk(self):      def walk(self):
317          """ D.walk() -> iterator over files and subdirs, recursively.          """ D.walk() -> iterator over files and subdirs, recursively.
318    
# Line 157  class path(_base): Line 336  class path(_base):
336                  yield child                  yield child
337                  for subsubdir in child.walkdirs():                  for subsubdir in child.walkdirs():
338                      yield subsubdir                      yield subsubdir
339    
340        def glob(self, pattern):
341            """ Return a list of path objects that match the pattern.
342    
343            pattern - a path relative to this directory, with wildcards.
344    
345            For example, path(os.getcwd()).glob('*.py') returns a list
346            of the Python files in the current directory.
347            """
348            return [path(name) for name in glob.glob(_base(self / pattern))]
349    
350    
351        # --- Create/delete operations on directories
352    
353        def mkdir(self):
354            os.mkdir(self)
355    
356        def makedirs(self):
357            os.makedirs(self)
358    
359        def rmdir(self):
360            os.rmdir(self)
361    
362        def removedirs(self):
363            os.removedirs(self)
364    
365    
366        # --- Read-only operations on files.
367    
368        def bytes(self):
369            """ Open this file, read all bytes, return them as a string. """
370            f = file(self, 'rb')
371            try:
372                return f.read()
373            finally:
374                f.close()
375    
376        def text(self, encoding=None, errors='strict'):
377            """ Open this file, read it in, return the content as a string.
378    
379            This uses 'U' mode in Python 2.3 and later.
380            """
381            f = file(self, _textmode)
382            try:
383                return f.read()
384            finally:
385                f.close()
386    
387        def lines(self, encoding=None, errors='strict'):
388            """ Open this file, read all lines, return them in a list.
389    
390            This uses 'U' mode in Python 2.3 and later.
391            """
392            f = file(self, _textmode)
393            try:
394                return f.readlines()
395            finally:
396                f.close()
397    
398    
399        # --- Modifying file operations
400    
401        def touch(self):
402            """ Set the access/modified times of this file to the current time.
403            Create the file if it does not exist.
404            """
405            fd = os.open(self, os.O_WRONLY | os.O_CREAT, 0666)
406            os.close(fd)
407            os.utime(self, None)
408    
409        def remove(self):
410            os.remove(self)
411    
412        def unlink(self):
413            os.unlink(self)
414    
415    
416        # --- Links
417    
418        if hasattr(os, 'link'):
419            def link(self, newpath):
420                """ Create a hard link at 'newpath', pointing to this file. """
421                os.link(self, newpath)
422    
423        if hasattr(os, 'symlink'):
424            def symlink(self, newlink):
425                """ Create a symbolic link at 'newlink', pointing here. """
426                os.symlink(self, newlink)
427    
428        if hasattr(os, 'readlink'):
429            def readlink(self):
430                """ Return the path to which this symbolic link points.
431    
432                The result may be an absolute or a relative path.
433                """
434                return path(os.readlink(self))
435    
436            def readlinkabs(self):
437                """ Return the path to which this symbolic link points.
438    
439                The result is always an absolute path.
440                """
441                p = self.readlink()
442                if p.isabs():
443                    return p
444                else:
445                    return (self.parent / p).abspath()
446    
447    
448        # --- High-level functions from shutil
449    
450        copyfile = shutil.copyfile
451        copymode = shutil.copymode
452        copystat = shutil.copystat
453        copy = shutil.copy
454        copy2 = shutil.copy2
455        copytree = shutil.copytree
456        if hasattr(shutil, 'move'):
457            move = shutil.move
458        rmtree = shutil.rmtree
459    
460    
461        # --- Special stuff from os
462    
463        if hasattr(os, 'chroot'):
464            def chroot(self):
465                os.chroot(self)
466    
467        if hasattr(os, 'startfile'):
468            def startfile(self):
469                os.startfile(self)
470    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26