METADATA 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. Metadata-Version: 2.1
  2. Name: scandir
  3. Version: 1.10.0
  4. Summary: scandir, a better directory iterator and faster os.walk()
  5. Home-page: https://github.com/benhoyt/scandir
  6. Author: Ben Hoyt
  7. Author-email: benhoyt@gmail.com
  8. License: New BSD License
  9. Platform: UNKNOWN
  10. Classifier: Development Status :: 5 - Production/Stable
  11. Classifier: Intended Audience :: Developers
  12. Classifier: Operating System :: OS Independent
  13. Classifier: License :: OSI Approved :: BSD License
  14. Classifier: Programming Language :: Python
  15. Classifier: Topic :: System :: Filesystems
  16. Classifier: Topic :: System :: Operating System
  17. Classifier: Programming Language :: Python
  18. Classifier: Programming Language :: Python :: 2
  19. Classifier: Programming Language :: Python :: 2.7
  20. Classifier: Programming Language :: Python :: 3
  21. Classifier: Programming Language :: Python :: 3.4
  22. Classifier: Programming Language :: Python :: 3.5
  23. Classifier: Programming Language :: Python :: 3.6
  24. Classifier: Programming Language :: Python :: 3.7
  25. Classifier: Programming Language :: Python :: Implementation :: CPython
  26. scandir, a better directory iterator and faster os.walk()
  27. =========================================================
  28. .. image:: https://img.shields.io/pypi/v/scandir.svg
  29. :target: https://pypi.python.org/pypi/scandir
  30. :alt: scandir on PyPI (Python Package Index)
  31. .. image:: https://travis-ci.org/benhoyt/scandir.svg?branch=master
  32. :target: https://travis-ci.org/benhoyt/scandir
  33. :alt: Travis CI tests (Linux)
  34. .. image:: https://ci.appveyor.com/api/projects/status/github/benhoyt/scandir?branch=master&svg=true
  35. :target: https://ci.appveyor.com/project/benhoyt/scandir
  36. :alt: Appveyor tests (Windows)
  37. ``scandir()`` is a directory iteration function like ``os.listdir()``,
  38. except that instead of returning a list of bare filenames, it yields
  39. ``DirEntry`` objects that include file type and stat information along
  40. with the name. Using ``scandir()`` increases the speed of ``os.walk()``
  41. by 2-20 times (depending on the platform and file system) by avoiding
  42. unnecessary calls to ``os.stat()`` in most cases.
  43. Now included in a Python near you!
  44. ----------------------------------
  45. ``scandir`` has been included in the Python 3.5 standard library as
  46. ``os.scandir()``, and the related performance improvements to
  47. ``os.walk()`` have also been included. So if you're lucky enough to be
  48. using Python 3.5 (release date September 13, 2015) you get the benefit
  49. immediately, otherwise just
  50. `download this module from PyPI <https://pypi.python.org/pypi/scandir>`_,
  51. install it with ``pip install scandir``, and then do something like
  52. this in your code:
  53. .. code-block:: python
  54. # Use the built-in version of scandir/walk if possible, otherwise
  55. # use the scandir module version
  56. try:
  57. from os import scandir, walk
  58. except ImportError:
  59. from scandir import scandir, walk
  60. `PEP 471 <https://www.python.org/dev/peps/pep-0471/>`_, which is the
  61. PEP that proposes including ``scandir`` in the Python standard library,
  62. was `accepted <https://mail.python.org/pipermail/python-dev/2014-July/135561.html>`_
  63. in July 2014 by Victor Stinner, the BDFL-delegate for the PEP.
  64. This ``scandir`` module is intended to work on Python 2.7+ and Python
  65. 3.4+ (and it has been tested on those versions).
  66. Background
  67. ----------
  68. Python's built-in ``os.walk()`` is significantly slower than it needs to be,
  69. because -- in addition to calling ``listdir()`` on each directory -- it calls
  70. ``stat()`` on each file to determine whether the filename is a directory or not.
  71. But both ``FindFirstFile`` / ``FindNextFile`` on Windows and ``readdir`` on Linux/OS
  72. X already tell you whether the files returned are directories or not, so
  73. no further ``stat`` system calls are needed. In short, you can reduce the number
  74. of system calls from about 2N to N, where N is the total number of files and
  75. directories in the tree.
  76. In practice, removing all those extra system calls makes ``os.walk()`` about
  77. **7-50 times as fast on Windows, and about 3-10 times as fast on Linux and Mac OS
  78. X.** So we're not talking about micro-optimizations. See more benchmarks
  79. in the "Benchmarks" section below.
  80. Somewhat relatedly, many people have also asked for a version of
  81. ``os.listdir()`` that yields filenames as it iterates instead of returning them
  82. as one big list. This improves memory efficiency for iterating very large
  83. directories.
  84. So as well as a faster ``walk()``, scandir adds a new ``scandir()`` function.
  85. They're pretty easy to use, but see "The API" below for the full docs.
  86. Benchmarks
  87. ----------
  88. Below are results showing how many times as fast ``scandir.walk()`` is than
  89. ``os.walk()`` on various systems, found by running ``benchmark.py`` with no
  90. arguments:
  91. ==================== ============== =============
  92. System version Python version Times as fast
  93. ==================== ============== =============
  94. Windows 7 64-bit 2.7.7 64-bit 10.4
  95. Windows 7 64-bit SSD 2.7.7 64-bit 10.3
  96. Windows 7 64-bit NFS 2.7.6 64-bit 36.8
  97. Windows 7 64-bit SSD 3.4.1 64-bit 9.9
  98. Windows 7 64-bit SSD 3.5.0 64-bit 9.5
  99. Ubuntu 14.04 64-bit 2.7.6 64-bit 5.8
  100. Mac OS X 10.9.3 2.7.5 64-bit 3.8
  101. ==================== ============== =============
  102. All of the above tests were done using the fast C version of scandir
  103. (source code in ``_scandir.c``).
  104. Note that the gains are less than the above on smaller directories and greater
  105. on larger directories. This is why ``benchmark.py`` creates a test directory
  106. tree with a standardized size.
  107. The API
  108. -------
  109. walk()
  110. ~~~~~~
  111. The API for ``scandir.walk()`` is exactly the same as ``os.walk()``, so just
  112. `read the Python docs <https://docs.python.org/3.5/library/os.html#os.walk>`_.
  113. scandir()
  114. ~~~~~~~~~
  115. The full docs for ``scandir()`` and the ``DirEntry`` objects it yields are
  116. available in the `Python documentation here <https://docs.python.org/3.5/library/os.html#os.scandir>`_.
  117. But below is a brief summary as well.
  118. scandir(path='.') -> iterator of DirEntry objects for given path
  119. Like ``listdir``, ``scandir`` calls the operating system's directory
  120. iteration system calls to get the names of the files in the given
  121. ``path``, but it's different from ``listdir`` in two ways:
  122. * Instead of returning bare filename strings, it returns lightweight
  123. ``DirEntry`` objects that hold the filename string and provide
  124. simple methods that allow access to the additional data the
  125. operating system may have returned.
  126. * It returns a generator instead of a list, so that ``scandir`` acts
  127. as a true iterator instead of returning the full list immediately.
  128. ``scandir()`` yields a ``DirEntry`` object for each file and
  129. sub-directory in ``path``. Just like ``listdir``, the ``'.'``
  130. and ``'..'`` pseudo-directories are skipped, and the entries are
  131. yielded in system-dependent order. Each ``DirEntry`` object has the
  132. following attributes and methods:
  133. * ``name``: the entry's filename, relative to the scandir ``path``
  134. argument (corresponds to the return values of ``os.listdir``)
  135. * ``path``: the entry's full path name (not necessarily an absolute
  136. path) -- the equivalent of ``os.path.join(scandir_path, entry.name)``
  137. * ``is_dir(*, follow_symlinks=True)``: similar to
  138. ``pathlib.Path.is_dir()``, but the return value is cached on the
  139. ``DirEntry`` object; doesn't require a system call in most cases;
  140. don't follow symbolic links if ``follow_symlinks`` is False
  141. * ``is_file(*, follow_symlinks=True)``: similar to
  142. ``pathlib.Path.is_file()``, but the return value is cached on the
  143. ``DirEntry`` object; doesn't require a system call in most cases;
  144. don't follow symbolic links if ``follow_symlinks`` is False
  145. * ``is_symlink()``: similar to ``pathlib.Path.is_symlink()``, but the
  146. return value is cached on the ``DirEntry`` object; doesn't require a
  147. system call in most cases
  148. * ``stat(*, follow_symlinks=True)``: like ``os.stat()``, but the
  149. return value is cached on the ``DirEntry`` object; does not require a
  150. system call on Windows (except for symlinks); don't follow symbolic links
  151. (like ``os.lstat()``) if ``follow_symlinks`` is False
  152. * ``inode()``: return the inode number of the entry; the return value
  153. is cached on the ``DirEntry`` object
  154. Here's a very simple example of ``scandir()`` showing use of the
  155. ``DirEntry.name`` attribute and the ``DirEntry.is_dir()`` method:
  156. .. code-block:: python
  157. def subdirs(path):
  158. """Yield directory names not starting with '.' under given path."""
  159. for entry in os.scandir(path):
  160. if not entry.name.startswith('.') and entry.is_dir():
  161. yield entry.name
  162. This ``subdirs()`` function will be significantly faster with scandir
  163. than ``os.listdir()`` and ``os.path.isdir()`` on both Windows and POSIX
  164. systems, especially on medium-sized or large directories.
  165. Further reading
  166. ---------------
  167. * `The Python docs for scandir <https://docs.python.org/3.5/library/os.html#os.scandir>`_
  168. * `PEP 471 <https://www.python.org/dev/peps/pep-0471/>`_, the
  169. (now-accepted) Python Enhancement Proposal that proposed adding
  170. ``scandir`` to the standard library -- a lot of details here,
  171. including rejected ideas and previous discussion
  172. Flames, comments, bug reports
  173. -----------------------------
  174. Please send flames, comments, and questions about scandir to Ben Hoyt:
  175. http://benhoyt.com/
  176. File bug reports for the version in the Python 3.5 standard library
  177. `here <https://docs.python.org/3.5/bugs.html>`_, or file bug reports
  178. or feature requests for this module at the GitHub project page:
  179. https://github.com/benhoyt/scandir