@@ -247,14 +247,41 @@ def _find_all_simple(path):
247247 """
248248 Find all files under 'path'
249249 """
250+ all_unique = _UniqueDirs .filter (os .walk (path , followlinks = True ))
250251 results = (
251252 os .path .join (base , file )
252- for base , dirs , files in os . walk ( path , followlinks = True )
253+ for base , dirs , files in all_unique
253254 for file in files
254255 )
255256 return filter (os .path .isfile , results )
256257
257258
259+ class _UniqueDirs (set ):
260+ """
261+ Exclude previously-seen dirs from walk results,
262+ avoiding infinite recursion.
263+ Ref https://bugs.python.org/issue44497.
264+ """
265+ def __call__ (self , walk_item ):
266+ """
267+ Given an item from an os.walk result, determine
268+ if the item represents a unique dir for this instance
269+ and if not, prevent further traversal.
270+ """
271+ base , dirs , files = walk_item
272+ stat = os .stat (base )
273+ candidate = stat .st_dev , stat .st_ino
274+ found = candidate in self
275+ if found :
276+ del dirs [:]
277+ self .add (candidate )
278+ return not found
279+
280+ @classmethod
281+ def filter (cls , items ):
282+ return filter (cls (), items )
283+
284+
258285def findall (dir = os .curdir ):
259286 """
260287 Find all files under 'dir' and return the list of full filenames.
0 commit comments