Bruno P. Kinoshita <> added the comment:


I did a quick `git bisect` using the example provided, and looks like this 
regression was added in the fix for bpo-33695, commit 

It looks to me that the iterator returned by with os.scandir(...) is including 
the newly created dst directory (see the call for `os.makedirs(dst, 
exist_ok=dirs_exist_ok)` in

This results in the function finding an extra directory, and repeating the 
steps for this folder and its subfolder recursively. This only happens because 
in the example in this issue, dst is a subdirectory of src.

The bpo-33695 commit had more changes, so I've reverted just this block of the 
copytree as a tentative fix, and added a unit test:


Here's a simplified version of what's going on:

import os
import shutil

shutil.rmtree('/tmp/test/', True)
with open('/tmp/test/foo', 'w+') as f:

# now we have /tmp/test/foo, let's simulate what happens in copytree on master

with os.scandir('/tmp/test') as entries:
  # up to this point, /tmp/test/foo is the only entry
  os.makedirs('/tmp/test/1/2/3/', exist_ok=True) # <---- when the iterator 
starts below in `f in entries`, it will find 1 too
  # now 1 will have been added too
  for f in entries:

nosy: +kinow

Python tracker <>
Python-bugs-list mailing list

Reply via email to