##// END OF EJS Templates
Added license statement to path.py, updated ChangeLog
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,807 +1,818 b''
1 1 """ path.py - An object representing a path to a file or directory.
2 2
3 3 Example:
4 4
5 5 from path import path
6 6 d = path('/home/guido/bin')
7 7 for f in d.files('*.py'):
8 8 f.chmod(0755)
9 9
10 10 This module requires Python 2.2 or later.
11 11
12 12
13 13 URL: http://www.jorendorff.com/articles/python/path
14 14 Author: Jason Orendorff <jason@jorendorff.com> (and others - see the url!)
15 15 Date: 7 Mar 2004
16 16 """
17 17
18 # Original license statement:
19 #License: You may use path.py for whatever you wish, at your own risk. (For
20 #example, you may modify, relicense, and redistribute it.) It is provided
21 #without any guarantee or warranty of any kind, not even for merchantability or
22 #fitness for any purpose.
23
24 # IPython license note:
25 # For the sake of convenience, IPython includes this module
26 # in its directory structure in unmodified form, apart from
27 # these license statements. The same license still applies.
28
18 29
19 30 # TODO
20 31 # - Bug in write_text(). It doesn't support Universal newline mode.
21 32 # - Better error message in listdir() when self isn't a
22 33 # directory. (On Windows, the error message really sucks.)
23 34 # - Make sure everything has a good docstring.
24 35 # - Add methods for regex find and replace.
25 36 # - guess_content_type() method?
26 37 # - Perhaps support arguments to touch().
27 38 # - Could add split() and join() methods that generate warnings.
28 39 # - Note: __add__() technically has a bug, I think, where
29 40 # it doesn't play nice with other types that implement
30 41 # __radd__(). Test this.
31 42
32 43 from __future__ import generators
33 44
34 45 import sys, os, fnmatch, glob, shutil, codecs
35 46
36 47 __version__ = '2.0.4'
37 48 __all__ = ['path']
38 49
39 50 # Pre-2.3 support. Are unicode filenames supported?
40 51 _base = str
41 52 try:
42 53 if os.path.supports_unicode_filenames:
43 54 _base = unicode
44 55 except AttributeError:
45 56 pass
46 57
47 58 # Pre-2.3 workaround for basestring.
48 59 try:
49 60 basestring
50 61 except NameError:
51 62 basestring = (str, unicode)
52 63
53 64 # Universal newline support
54 65 _textmode = 'r'
55 66 if hasattr(file, 'newlines'):
56 67 _textmode = 'U'
57 68
58 69
59 70 class path(_base):
60 71 """ Represents a filesystem path.
61 72
62 73 For documentation on individual methods, consult their
63 74 counterparts in os.path.
64 75 """
65 76
66 77 # --- Special Python methods.
67 78
68 79 def __repr__(self):
69 80 return 'path(%s)' % _base.__repr__(self)
70 81
71 82 # Adding a path and a string yields a path.
72 83 def __add__(self, more):
73 84 return path(_base(self) + more)
74 85
75 86 def __radd__(self, other):
76 87 return path(other + _base(self))
77 88
78 89 # The / operator joins paths.
79 90 def __div__(self, rel):
80 91 """ fp.__div__(rel) == fp / rel == fp.joinpath(rel)
81 92
82 93 Join two path components, adding a separator character if
83 94 needed.
84 95 """
85 96 return path(os.path.join(self, rel))
86 97
87 98 # Make the / operator work even when true division is enabled.
88 99 __truediv__ = __div__
89 100
90 101 def getcwd():
91 102 """ Return the current working directory as a path object. """
92 103 return path(os.getcwd())
93 104 getcwd = staticmethod(getcwd)
94 105
95 106
96 107 # --- Operations on path strings.
97 108
98 109 def abspath(self): return path(os.path.abspath(self))
99 110 def normcase(self): return path(os.path.normcase(self))
100 111 def normpath(self): return path(os.path.normpath(self))
101 112 def realpath(self): return path(os.path.realpath(self))
102 113 def expanduser(self): return path(os.path.expanduser(self))
103 114 def expandvars(self): return path(os.path.expandvars(self))
104 115 def dirname(self): return path(os.path.dirname(self))
105 116 basename = os.path.basename
106 117
107 118 def expand(self):
108 119 """ Clean up a filename by calling expandvars(),
109 120 expanduser(), and normpath() on it.
110 121
111 122 This is commonly everything needed to clean up a filename
112 123 read from a configuration file, for example.
113 124 """
114 125 return self.expandvars().expanduser().normpath()
115 126
116 127 def _get_namebase(self):
117 128 base, ext = os.path.splitext(self.name)
118 129 return base
119 130
120 131 def _get_ext(self):
121 132 f, ext = os.path.splitext(_base(self))
122 133 return ext
123 134
124 135 def _get_drive(self):
125 136 drive, r = os.path.splitdrive(self)
126 137 return path(drive)
127 138
128 139 parent = property(
129 140 dirname, None, None,
130 141 """ This path's parent directory, as a new path object.
131 142
132 143 For example, path('/usr/local/lib/libpython.so').parent == path('/usr/local/lib')
133 144 """)
134 145
135 146 name = property(
136 147 basename, None, None,
137 148 """ The name of this file or directory without the full path.
138 149
139 150 For example, path('/usr/local/lib/libpython.so').name == 'libpython.so'
140 151 """)
141 152
142 153 namebase = property(
143 154 _get_namebase, None, None,
144 155 """ The same as path.name, but with one file extension stripped off.
145 156
146 157 For example, path('/home/guido/python.tar.gz').name == 'python.tar.gz',
147 158 but path('/home/guido/python.tar.gz').namebase == 'python.tar'
148 159 """)
149 160
150 161 ext = property(
151 162 _get_ext, None, None,
152 163 """ The file extension, for example '.py'. """)
153 164
154 165 drive = property(
155 166 _get_drive, None, None,
156 167 """ The drive specifier, for example 'C:'.
157 168 This is always empty on systems that don't use drive specifiers.
158 169 """)
159 170
160 171 def splitpath(self):
161 172 """ p.splitpath() -> Return (p.parent, p.name). """
162 173 parent, child = os.path.split(self)
163 174 return path(parent), child
164 175
165 176 def splitdrive(self):
166 177 """ p.splitdrive() -> Return (p.drive, <the rest of p>).
167 178
168 179 Split the drive specifier from this path. If there is
169 180 no drive specifier, p.drive is empty, so the return value
170 181 is simply (path(''), p). This is always the case on Unix.
171 182 """
172 183 drive, rel = os.path.splitdrive(self)
173 184 return path(drive), rel
174 185
175 186 def splitext(self):
176 187 """ p.splitext() -> Return (p.stripext(), p.ext).
177 188
178 189 Split the filename extension from this path and return
179 190 the two parts. Either part may be empty.
180 191
181 192 The extension is everything from '.' to the end of the
182 193 last path segment. This has the property that if
183 194 (a, b) == p.splitext(), then a + b == p.
184 195 """
185 196 filename, ext = os.path.splitext(self)
186 197 return path(filename), ext
187 198
188 199 def stripext(self):
189 200 """ p.stripext() -> Remove one file extension from the path.
190 201
191 202 For example, path('/home/guido/python.tar.gz').stripext()
192 203 returns path('/home/guido/python.tar').
193 204 """
194 205 return self.splitext()[0]
195 206
196 207 if hasattr(os.path, 'splitunc'):
197 208 def splitunc(self):
198 209 unc, rest = os.path.splitunc(self)
199 210 return path(unc), rest
200 211
201 212 def _get_uncshare(self):
202 213 unc, r = os.path.splitunc(self)
203 214 return path(unc)
204 215
205 216 uncshare = property(
206 217 _get_uncshare, None, None,
207 218 """ The UNC mount point for this path.
208 219 This is empty for paths on local drives. """)
209 220
210 221 def joinpath(self, *args):
211 222 """ Join two or more path components, adding a separator
212 223 character (os.sep) if needed. Returns a new path
213 224 object.
214 225 """
215 226 return path(os.path.join(self, *args))
216 227
217 228 def splitall(self):
218 229 """ Return a list of the path components in this path.
219 230
220 231 The first item in the list will be a path. Its value will be
221 232 either os.curdir, os.pardir, empty, or the root directory of
222 233 this path (for example, '/' or 'C:\\'). The other items in
223 234 the list will be strings.
224 235
225 236 path.path.joinpath(*result) will yield the original path.
226 237 """
227 238 parts = []
228 239 loc = self
229 240 while loc != os.curdir and loc != os.pardir:
230 241 prev = loc
231 242 loc, child = prev.splitpath()
232 243 if loc == prev:
233 244 break
234 245 parts.append(child)
235 246 parts.append(loc)
236 247 parts.reverse()
237 248 return parts
238 249
239 250 def relpath(self):
240 251 """ Return this path as a relative path,
241 252 based from the current working directory.
242 253 """
243 254 cwd = path(os.getcwd())
244 255 return cwd.relpathto(self)
245 256
246 257 def relpathto(self, dest):
247 258 """ Return a relative path from self to dest.
248 259
249 260 If there is no relative path from self to dest, for example if
250 261 they reside on different drives in Windows, then this returns
251 262 dest.abspath().
252 263 """
253 264 origin = self.abspath()
254 265 dest = path(dest).abspath()
255 266
256 267 orig_list = origin.normcase().splitall()
257 268 # Don't normcase dest! We want to preserve the case.
258 269 dest_list = dest.splitall()
259 270
260 271 if orig_list[0] != os.path.normcase(dest_list[0]):
261 272 # Can't get here from there.
262 273 return dest
263 274
264 275 # Find the location where the two paths start to differ.
265 276 i = 0
266 277 for start_seg, dest_seg in zip(orig_list, dest_list):
267 278 if start_seg != os.path.normcase(dest_seg):
268 279 break
269 280 i += 1
270 281
271 282 # Now i is the point where the two paths diverge.
272 283 # Need a certain number of "os.pardir"s to work up
273 284 # from the origin to the point of divergence.
274 285 segments = [os.pardir] * (len(orig_list) - i)
275 286 # Need to add the diverging part of dest_list.
276 287 segments += dest_list[i:]
277 288 if len(segments) == 0:
278 289 # If they happen to be identical, use os.curdir.
279 290 return path(os.curdir)
280 291 else:
281 292 return path(os.path.join(*segments))
282 293
283 294
284 295 # --- Listing, searching, walking, and matching
285 296
286 297 def listdir(self, pattern=None):
287 298 """ D.listdir() -> List of items in this directory.
288 299
289 300 Use D.files() or D.dirs() instead if you want a listing
290 301 of just files or just subdirectories.
291 302
292 303 The elements of the list are path objects.
293 304
294 305 With the optional 'pattern' argument, this only lists
295 306 items whose names match the given pattern.
296 307 """
297 308 names = os.listdir(self)
298 309 if pattern is not None:
299 310 names = fnmatch.filter(names, pattern)
300 311 return [self / child for child in names]
301 312
302 313 def dirs(self, pattern=None):
303 314 """ D.dirs() -> List of this directory's subdirectories.
304 315
305 316 The elements of the list are path objects.
306 317 This does not walk recursively into subdirectories
307 318 (but see path.walkdirs).
308 319
309 320 With the optional 'pattern' argument, this only lists
310 321 directories whose names match the given pattern. For
311 322 example, d.dirs('build-*').
312 323 """
313 324 return [p for p in self.listdir(pattern) if p.isdir()]
314 325
315 326 def files(self, pattern=None):
316 327 """ D.files() -> List of the files in this directory.
317 328
318 329 The elements of the list are path objects.
319 330 This does not walk into subdirectories (see path.walkfiles).
320 331
321 332 With the optional 'pattern' argument, this only lists files
322 333 whose names match the given pattern. For example,
323 334 d.files('*.pyc').
324 335 """
325 336
326 337 return [p for p in self.listdir(pattern) if p.isfile()]
327 338
328 339 def walk(self, pattern=None):
329 340 """ D.walk() -> iterator over files and subdirs, recursively.
330 341
331 342 The iterator yields path objects naming each child item of
332 343 this directory and its descendants. This requires that
333 344 D.isdir().
334 345
335 346 This performs a depth-first traversal of the directory tree.
336 347 Each directory is returned just before all its children.
337 348 """
338 349 for child in self.listdir():
339 350 if pattern is None or child.fnmatch(pattern):
340 351 yield child
341 352 if child.isdir():
342 353 for item in child.walk(pattern):
343 354 yield item
344 355
345 356 def walkdirs(self, pattern=None):
346 357 """ D.walkdirs() -> iterator over subdirs, recursively.
347 358
348 359 With the optional 'pattern' argument, this yields only
349 360 directories whose names match the given pattern. For
350 361 example, mydir.walkdirs('*test') yields only directories
351 362 with names ending in 'test'.
352 363 """
353 364 for child in self.dirs():
354 365 if pattern is None or child.fnmatch(pattern):
355 366 yield child
356 367 for subsubdir in child.walkdirs(pattern):
357 368 yield subsubdir
358 369
359 370 def walkfiles(self, pattern=None):
360 371 """ D.walkfiles() -> iterator over files in D, recursively.
361 372
362 373 The optional argument, pattern, limits the results to files
363 374 with names that match the pattern. For example,
364 375 mydir.walkfiles('*.tmp') yields only files with the .tmp
365 376 extension.
366 377 """
367 378 for child in self.listdir():
368 379 if child.isfile():
369 380 if pattern is None or child.fnmatch(pattern):
370 381 yield child
371 382 elif child.isdir():
372 383 for f in child.walkfiles(pattern):
373 384 yield f
374 385
375 386 def fnmatch(self, pattern):
376 387 """ Return True if self.name matches the given pattern.
377 388
378 389 pattern - A filename pattern with wildcards,
379 390 for example '*.py'.
380 391 """
381 392 return fnmatch.fnmatch(self.name, pattern)
382 393
383 394 def glob(self, pattern):
384 395 """ Return a list of path objects that match the pattern.
385 396
386 397 pattern - a path relative to this directory, with wildcards.
387 398
388 399 For example, path('/users').glob('*/bin/*') returns a list
389 400 of all the files users have in their bin directories.
390 401 """
391 402 return map(path, glob.glob(_base(self / pattern)))
392 403
393 404
394 405 # --- Reading or writing an entire file at once.
395 406
396 407 def open(self, mode='r'):
397 408 """ Open this file. Return a file object. """
398 409 return file(self, mode)
399 410
400 411 def bytes(self):
401 412 """ Open this file, read all bytes, return them as a string. """
402 413 f = self.open('rb')
403 414 try:
404 415 return f.read()
405 416 finally:
406 417 f.close()
407 418
408 419 def write_bytes(self, bytes, append=False):
409 420 """ Open this file and write the given bytes to it.
410 421
411 422 Default behavior is to overwrite any existing file.
412 423 Call this with write_bytes(bytes, append=True) to append instead.
413 424 """
414 425 if append:
415 426 mode = 'ab'
416 427 else:
417 428 mode = 'wb'
418 429 f = self.open(mode)
419 430 try:
420 431 f.write(bytes)
421 432 finally:
422 433 f.close()
423 434
424 435 def text(self, encoding=None, errors='strict'):
425 436 """ Open this file, read it in, return the content as a string.
426 437
427 438 This uses 'U' mode in Python 2.3 and later, so '\r\n' and '\r'
428 439 are automatically translated to '\n'.
429 440
430 441 Optional arguments:
431 442
432 443 encoding - The Unicode encoding (or character set) of
433 444 the file. If present, the content of the file is
434 445 decoded and returned as a unicode object; otherwise
435 446 it is returned as an 8-bit str.
436 447 errors - How to handle Unicode errors; see help(str.decode)
437 448 for the options. Default is 'strict'.
438 449 """
439 450 if encoding is None:
440 451 # 8-bit
441 452 f = self.open(_textmode)
442 453 try:
443 454 return f.read()
444 455 finally:
445 456 f.close()
446 457 else:
447 458 # Unicode
448 459 f = codecs.open(self, 'r', encoding, errors)
449 460 # (Note - Can't use 'U' mode here, since codecs.open
450 461 # doesn't support 'U' mode, even in Python 2.3.)
451 462 try:
452 463 t = f.read()
453 464 finally:
454 465 f.close()
455 466 return (t.replace(u'\r\n', u'\n')
456 467 .replace(u'\r\x85', u'\n')
457 468 .replace(u'\r', u'\n')
458 469 .replace(u'\x85', u'\n')
459 470 .replace(u'\u2028', u'\n'))
460 471
461 472 def write_text(self, text, encoding=None, errors='strict', linesep=os.linesep, append=False):
462 473 """ Write the given text to this file.
463 474
464 475 The default behavior is to overwrite any existing file;
465 476 to append instead, use the 'append=True' keyword argument.
466 477
467 478 There are two differences between path.write_text() and
468 479 path.write_bytes(): newline handling and Unicode handling.
469 480 See below.
470 481
471 482 Parameters:
472 483
473 484 - text - str/unicode - The text to be written.
474 485
475 486 - encoding - str - The Unicode encoding that will be used.
476 487 This is ignored if 'text' isn't a Unicode string.
477 488
478 489 - errors - str - How to handle Unicode encoding errors.
479 490 Default is 'strict'. See help(unicode.encode) for the
480 491 options. This is ignored if 'text' isn't a Unicode
481 492 string.
482 493
483 494 - linesep - keyword argument - str/unicode - The sequence of
484 495 characters to be used to mark end-of-line. The default is
485 496 os.linesep. You can also specify None; this means to
486 497 leave all newlines as they are in 'text'.
487 498
488 499 - append - keyword argument - bool - Specifies what to do if
489 500 the file already exists (True: append to the end of it;
490 501 False: overwrite it.) The default is False.
491 502
492 503
493 504 --- Newline handling.
494 505
495 506 write_text() converts all standard end-of-line sequences
496 507 ('\n', '\r', and '\r\n') to your platform's default end-of-line
497 508 sequence (see os.linesep; on Windows, for example, the
498 509 end-of-line marker is '\r\n').
499 510
500 511 If you don't like your platform's default, you can override it
501 512 using the 'linesep=' keyword argument. If you specifically want
502 513 write_text() to preserve the newlines as-is, use 'linesep=None'.
503 514
504 515 This applies to Unicode text the same as to 8-bit text, except
505 516 there are three additional standard Unicode end-of-line sequences:
506 517 u'\x85', u'\r\x85', and u'\u2028'.
507 518
508 519 (This is slightly different from when you open a file for
509 520 writing with fopen(filename, "w") in C or file(filename, 'w')
510 521 in Python.)
511 522
512 523
513 524 --- Unicode
514 525
515 526 If 'text' isn't Unicode, then apart from newline handling, the
516 527 bytes are written verbatim to the file. The 'encoding' and
517 528 'errors' arguments are not used and must be omitted.
518 529
519 530 If 'text' is Unicode, it is first converted to bytes using the
520 531 specified 'encoding' (or the default encoding if 'encoding'
521 532 isn't specified). The 'errors' argument applies only to this
522 533 conversion.
523 534
524 535 """
525 536 if isinstance(text, unicode):
526 537 if linesep is not None:
527 538 # Convert all standard end-of-line sequences to
528 539 # ordinary newline characters.
529 540 text = (text.replace(u'\r\n', u'\n')
530 541 .replace(u'\r\x85', u'\n')
531 542 .replace(u'\r', u'\n')
532 543 .replace(u'\x85', u'\n')
533 544 .replace(u'\u2028', u'\n'))
534 545 text = text.replace(u'\n', linesep)
535 546 if encoding is None:
536 547 encoding = sys.getdefaultencoding()
537 548 bytes = text.encode(encoding, errors)
538 549 else:
539 550 # It is an error to specify an encoding if 'text' is
540 551 # an 8-bit string.
541 552 assert encoding is None
542 553
543 554 if linesep is not None:
544 555 text = (text.replace('\r\n', '\n')
545 556 .replace('\r', '\n'))
546 557 bytes = text.replace('\n', linesep)
547 558
548 559 self.write_bytes(bytes, append)
549 560
550 561 def lines(self, encoding=None, errors='strict', retain=True):
551 562 """ Open this file, read all lines, return them in a list.
552 563
553 564 Optional arguments:
554 565 encoding - The Unicode encoding (or character set) of
555 566 the file. The default is None, meaning the content
556 567 of the file is read as 8-bit characters and returned
557 568 as a list of (non-Unicode) str objects.
558 569 errors - How to handle Unicode errors; see help(str.decode)
559 570 for the options. Default is 'strict'
560 571 retain - If true, retain newline characters; but all newline
561 572 character combinations ('\r', '\n', '\r\n') are
562 573 translated to '\n'. If false, newline characters are
563 574 stripped off. Default is True.
564 575
565 576 This uses 'U' mode in Python 2.3 and later.
566 577 """
567 578 if encoding is None and retain:
568 579 f = self.open(_textmode)
569 580 try:
570 581 return f.readlines()
571 582 finally:
572 583 f.close()
573 584 else:
574 585 return self.text(encoding, errors).splitlines(retain)
575 586
576 587 def write_lines(self, lines, encoding=None, errors='strict',
577 588 linesep=os.linesep, append=False):
578 589 """ Write the given lines of text to this file.
579 590
580 591 By default this overwrites any existing file at this path.
581 592
582 593 This puts a platform-specific newline sequence on every line.
583 594 See 'linesep' below.
584 595
585 596 lines - A list of strings.
586 597
587 598 encoding - A Unicode encoding to use. This applies only if
588 599 'lines' contains any Unicode strings.
589 600
590 601 errors - How to handle errors in Unicode encoding. This
591 602 also applies only to Unicode strings.
592 603
593 604 linesep - The desired line-ending. This line-ending is
594 605 applied to every line. If a line already has any
595 606 standard line ending ('\r', '\n', '\r\n', u'\x85',
596 607 u'\r\x85', u'\u2028'), that will be stripped off and
597 608 this will be used instead. The default is os.linesep,
598 609 which is platform-dependent ('\r\n' on Windows, '\n' on
599 610 Unix, etc.) Specify None to write the lines as-is,
600 611 like file.writelines().
601 612
602 613 Use the keyword argument append=True to append lines to the
603 614 file. The default is to overwrite the file. Warning:
604 615 When you use this with Unicode data, if the encoding of the
605 616 existing data in the file is different from the encoding
606 617 you specify with the encoding= parameter, the result is
607 618 mixed-encoding data, which can really confuse someone trying
608 619 to read the file later.
609 620 """
610 621 if append:
611 622 mode = 'ab'
612 623 else:
613 624 mode = 'wb'
614 625 f = self.open(mode)
615 626 try:
616 627 for line in lines:
617 628 isUnicode = isinstance(line, unicode)
618 629 if linesep is not None:
619 630 # Strip off any existing line-end and add the
620 631 # specified linesep string.
621 632 if isUnicode:
622 633 if line[-2:] in (u'\r\n', u'\x0d\x85'):
623 634 line = line[:-2]
624 635 elif line[-1:] in (u'\r', u'\n',
625 636 u'\x85', u'\u2028'):
626 637 line = line[:-1]
627 638 else:
628 639 if line[-2:] == '\r\n':
629 640 line = line[:-2]
630 641 elif line[-1:] in ('\r', '\n'):
631 642 line = line[:-1]
632 643 line += linesep
633 644 if isUnicode:
634 645 if encoding is None:
635 646 encoding = sys.getdefaultencoding()
636 647 line = line.encode(encoding, errors)
637 648 f.write(line)
638 649 finally:
639 650 f.close()
640 651
641 652
642 653 # --- Methods for querying the filesystem.
643 654
644 655 exists = os.path.exists
645 656 isabs = os.path.isabs
646 657 isdir = os.path.isdir
647 658 isfile = os.path.isfile
648 659 islink = os.path.islink
649 660 ismount = os.path.ismount
650 661
651 662 if hasattr(os.path, 'samefile'):
652 663 samefile = os.path.samefile
653 664
654 665 getatime = os.path.getatime
655 666 atime = property(
656 667 getatime, None, None,
657 668 """ Last access time of the file. """)
658 669
659 670 getmtime = os.path.getmtime
660 671 mtime = property(
661 672 getmtime, None, None,
662 673 """ Last-modified time of the file. """)
663 674
664 675 if hasattr(os.path, 'getctime'):
665 676 getctime = os.path.getctime
666 677 ctime = property(
667 678 getctime, None, None,
668 679 """ Creation time of the file. """)
669 680
670 681 getsize = os.path.getsize
671 682 size = property(
672 683 getsize, None, None,
673 684 """ Size of the file, in bytes. """)
674 685
675 686 if hasattr(os, 'access'):
676 687 def access(self, mode):
677 688 """ Return true if current user has access to this path.
678 689
679 690 mode - One of the constants os.F_OK, os.R_OK, os.W_OK, os.X_OK
680 691 """
681 692 return os.access(self, mode)
682 693
683 694 def stat(self):
684 695 """ Perform a stat() system call on this path. """
685 696 return os.stat(self)
686 697
687 698 def lstat(self):
688 699 """ Like path.stat(), but do not follow symbolic links. """
689 700 return os.lstat(self)
690 701
691 702 if hasattr(os, 'statvfs'):
692 703 def statvfs(self):
693 704 """ Perform a statvfs() system call on this path. """
694 705 return os.statvfs(self)
695 706
696 707 if hasattr(os, 'pathconf'):
697 708 def pathconf(self, name):
698 709 return os.pathconf(self, name)
699 710
700 711
701 712 # --- Modifying operations on files and directories
702 713
703 714 def utime(self, times):
704 715 """ Set the access and modified times of this file. """
705 716 os.utime(self, times)
706 717
707 718 def chmod(self, mode):
708 719 os.chmod(self, mode)
709 720
710 721 if hasattr(os, 'chown'):
711 722 def chown(self, uid, gid):
712 723 os.chown(self, uid, gid)
713 724
714 725 def rename(self, new):
715 726 os.rename(self, new)
716 727
717 728 def renames(self, new):
718 729 os.renames(self, new)
719 730
720 731
721 732 # --- Create/delete operations on directories
722 733
723 734 def mkdir(self, mode=0777):
724 735 os.mkdir(self, mode)
725 736
726 737 def makedirs(self, mode=0777):
727 738 os.makedirs(self, mode)
728 739
729 740 def rmdir(self):
730 741 os.rmdir(self)
731 742
732 743 def removedirs(self):
733 744 os.removedirs(self)
734 745
735 746
736 747 # --- Modifying operations on files
737 748
738 749 def touch(self):
739 750 """ Set the access/modified times of this file to the current time.
740 751 Create the file if it does not exist.
741 752 """
742 753 fd = os.open(self, os.O_WRONLY | os.O_CREAT, 0666)
743 754 os.close(fd)
744 755 os.utime(self, None)
745 756
746 757 def remove(self):
747 758 os.remove(self)
748 759
749 760 def unlink(self):
750 761 os.unlink(self)
751 762
752 763
753 764 # --- Links
754 765
755 766 if hasattr(os, 'link'):
756 767 def link(self, newpath):
757 768 """ Create a hard link at 'newpath', pointing to this file. """
758 769 os.link(self, newpath)
759 770
760 771 if hasattr(os, 'symlink'):
761 772 def symlink(self, newlink):
762 773 """ Create a symbolic link at 'newlink', pointing here. """
763 774 os.symlink(self, newlink)
764 775
765 776 if hasattr(os, 'readlink'):
766 777 def readlink(self):
767 778 """ Return the path to which this symbolic link points.
768 779
769 780 The result may be an absolute or a relative path.
770 781 """
771 782 return path(os.readlink(self))
772 783
773 784 def readlinkabs(self):
774 785 """ Return the path to which this symbolic link points.
775 786
776 787 The result is always an absolute path.
777 788 """
778 789 p = self.readlink()
779 790 if p.isabs():
780 791 return p
781 792 else:
782 793 return (self.parent / p).abspath()
783 794
784 795
785 796 # --- High-level functions from shutil
786 797
787 798 copyfile = shutil.copyfile
788 799 copymode = shutil.copymode
789 800 copystat = shutil.copystat
790 801 copy = shutil.copy
791 802 copy2 = shutil.copy2
792 803 copytree = shutil.copytree
793 804 if hasattr(shutil, 'move'):
794 805 move = shutil.move
795 806 rmtree = shutil.rmtree
796 807
797 808
798 809 # --- Special stuff from os
799 810
800 811 if hasattr(os, 'chroot'):
801 812 def chroot(self):
802 813 os.chroot(self)
803 814
804 815 if hasattr(os, 'startfile'):
805 816 def startfile(self):
806 817 os.startfile(self)
807 818
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now