glob.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. """Filename globbing utility."""
  2. import sys
  3. import os
  4. import re
  5. import fnmatch
  6. try:
  7. _unicode = unicode
  8. except NameError:
  9. # If Python is built without Unicode support, the unicode type
  10. # will not exist. Fake one.
  11. class _unicode(object):
  12. pass
  13. __all__ = ["glob", "iglob"]
  14. def glob(pathname):
  15. """Return a list of paths matching a pathname pattern.
  16. The pattern may contain simple shell-style wildcards a la
  17. fnmatch. However, unlike fnmatch, filenames starting with a
  18. dot are special cases that are not matched by '*' and '?'
  19. patterns.
  20. """
  21. return list(iglob(pathname))
  22. def iglob(pathname):
  23. """Return an iterator which yields the paths matching a pathname pattern.
  24. The pattern may contain simple shell-style wildcards a la
  25. fnmatch. However, unlike fnmatch, filenames starting with a
  26. dot are special cases that are not matched by '*' and '?'
  27. patterns.
  28. """
  29. dirname, basename = os.path.split(pathname)
  30. if not has_magic(pathname):
  31. if basename:
  32. if os.path.lexists(pathname):
  33. yield pathname
  34. else:
  35. # Patterns ending with a slash should match only directories
  36. if os.path.isdir(dirname):
  37. yield pathname
  38. return
  39. if not dirname:
  40. for name in glob1(os.curdir, basename):
  41. yield name
  42. return
  43. # `os.path.split()` returns the argument itself as a dirname if it is a
  44. # drive or UNC path. Prevent an infinite recursion if a drive or UNC path
  45. # contains magic characters (i.e. r'\\?\C:').
  46. if dirname != pathname and has_magic(dirname):
  47. dirs = iglob(dirname)
  48. else:
  49. dirs = [dirname]
  50. if has_magic(basename):
  51. glob_in_dir = glob1
  52. else:
  53. glob_in_dir = glob0
  54. for dirname in dirs:
  55. for name in glob_in_dir(dirname, basename):
  56. yield os.path.join(dirname, name)
  57. # These 2 helper functions non-recursively glob inside a literal directory.
  58. # They return a list of basenames. `glob1` accepts a pattern while `glob0`
  59. # takes a literal basename (so it only has to check for its existence).
  60. def glob1(dirname, pattern):
  61. if not dirname:
  62. dirname = os.curdir
  63. if isinstance(pattern, _unicode) and not isinstance(dirname, unicode):
  64. dirname = unicode(dirname, sys.getfilesystemencoding() or
  65. sys.getdefaultencoding())
  66. try:
  67. names = os.listdir(dirname)
  68. except os.error:
  69. return []
  70. if pattern[0] != '.':
  71. names = filter(lambda x: x[0] != '.', names)
  72. return fnmatch.filter(names, pattern)
  73. def glob0(dirname, basename):
  74. if basename == '':
  75. # `os.path.split()` returns an empty basename for paths ending with a
  76. # directory separator. 'q*x/' should match only directories.
  77. if os.path.isdir(dirname):
  78. return [basename]
  79. else:
  80. if os.path.lexists(os.path.join(dirname, basename)):
  81. return [basename]
  82. return []
  83. magic_check = re.compile('[*?[]')
  84. def has_magic(s):
  85. return magic_check.search(s) is not None