Using iterative filesystem walk instead of recursive

I hope I’m not being too keen here, but I’m increasingly convinced that fixing shutil.rmtree() by building upon pathlib.Path.walk() is the right way to go. The process looks like this:

  1. Add pathlib.Path.fwalk() method, so we can avoid symlink races in rmtree()
    • Nicely complements the walk() method we added in 3.12.
    • Draft PR here
  2. Add optional follow_junctions argument to pathlib.Path.walk(), so we can avoid walking into junctions on Windows in rmtree()
    • A small patch.
  3. Implement shutil.rmtree() using pathlib.Path.walk() and fwalk()
    • This makes shutil.py about 100 lines shorter, and the rmtree() algorithm more obvious.

Note how we don’t need a function/method that yields os.DirEntry objects at any stage, so this strikes me as the least invasive way to solve the problem. If/when we introduce scantree(), we could always revisit the rmtree() implementation.

Also pinging @Ovsyanka, who previously brought up adding Path.fwalk().