Author kinow
Recipients cboltz, giampaolo.rodola, kinow
Date 2019-11-09.13:26:16
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1573305976.69.0.63189632597.issue38688@roundup.psfhosted.org>
In-reply-to
Content
Hi,

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

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 https://github.com/python/cpython/blob/e27449da92b13730a5e11182f329d5da98a5e05b/Lib/shutil.py#L449).

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: https://github.com/python/cpython/pull/17098

--

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

```
import os
import shutil

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

# 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:
    print(f)
```
History
Date User Action Args
2019-11-09 13:26:16kinowsetrecipients: + kinow, giampaolo.rodola, cboltz
2019-11-09 13:26:16kinowsetmessageid: <1573305976.69.0.63189632597.issue38688@roundup.psfhosted.org>
2019-11-09 13:26:16kinowlinkissue38688 messages
2019-11-09 13:26:16kinowcreate