New GitHub issue #102932 from barneygale:<br>

<hr>

<pre>
Prior to the fix for #89727, it was possible influence which subdirectories were visited by `os.walk()` **even after** the walk had descended into siblings of those subdirectories. Such "late" modifications no longer have any effect.

This was [reported](https://github.com/python/cpython/issues/89727#issuecomment-1369298204) by @pochmann:

> I think you changed `os.walk`'s behavior. The recursive one supported late modifications of subdirs lists, due to being lazier. The iterative one doesn't (if I'm not mistaken... I can't test).

> With topdown, you can modify a directory's subdirs, for example remove one and it won't be visited. Usually you'd do that while your walk is on that parent directory. But with the recursive one, it was possible to do it later. With the iterative one, I don't think that works anymore.

> Here's a demo where I remove the second subdir after having walked onto the first:

> ```python
> import os

> # Create demo dir with three subdirs
> os.makedirs('demo/a')
> os.makedirs('demo/b')
> os.makedirs('demo/c')

> # Walk onto "demo"
> walk = os.walk('demo')
> demo = next(walk)
> print(demo)

> # Walk onto first subdir
> first = next(walk)
> print(first)

> # Remove the second subdir
> del demo[1][1]

> # Walk onto the remaining subdirs
> for x in walk:
>     print(x)
> ```

> Output ([Try it online!](https://tio.run/##bZCxDoJADIb3e4pGB2HBGBdj4uQbuDgYh0OKXJArOarg02MLaqLhckPv69/@vdZPLsivN3Xoe1fVFBioMWYO@4CWETKsCDIXoHVcABcBEZp7KqQx1CSVLVHjaKHCpV3EEzSdpBeh4nO0txLIM8FM8cy0CnYyRaLRKBbpMMgOPHYcaSI2dXCeI@V/jXIx4feUZnxMFA6JofIgLR4on5Ov4YV89qnN8DYs4LQ6y/01UXXAyjrv/PW7kpwCdOA8qNPWgJzRrYv7/gU)), note that the second subdir wasn't walked:

> ```python
> ('demo', ['c', 'a', 'b'], [])
> ('demo/c', [], [])
> ('demo/b', [], [])
> ```

> [Excerpt from the recursive one](https://github.com/python/cpython/blob/a7a450f84a087421603170c2dad226bb881d4d9a/Lib/os.py#L412-L419):

> ```python
>         for dirname in dirs:
>             new_path = join(top, dirname)
>             yield from _walk(new_path, topdown, onerror, followlinks)
> ```

> The iteration of `dirs` and the walking of the subdirs are intertwined. After walking a subdir, the paused iteration of `dirs` resumes. That allows the late modifications of `dirs` to have an effect.

> [Excerpt from the iterative one](https://github.com/python/cpython/blob/73097d91a64620ae7f620705864b84234d85cc82/Lib/os.py#L418-L425):

> ```python
>             for dirname in reversed(dirs):
> new_path = join(top, dirname)
> stack.append(new_path)
> ```

> This eagerly puts all subdirs onto the stack, before they're getting walked, and then `dirs` is never used again. So modifying `dirs` during the subdirs walking doesn't have an effect anymore.
</pre>

<hr>

<a href="https://github.com/python/cpython/issues/102932">View on GitHub</a>
<p>Labels: type-bug, 3.12</p>
<p>Assignee: </p>