python / python/cpython

Support `exist_ok` for `pathlib`'s `Path.copy_into()`

未關閉
#143,052 4 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

pending stdlib topic-pathlib type-feature
主要語言
Python
星號
77.2k
分支
35.9k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:
Background

The Path.copy_into() method (introduced in Python 3.14) is used to copy files or directories into another directory.
The behaviour of files being copied and directories being copied is inconsistent when the destination directory contains a file or directory with the same name.

Examples

When a file is copied into a directory that already has a file with that name, the copied file overwrites the file at the destination directory:

"""
# Copying a file into a directory that already has a file with the same name #

Directory Structure:
dir_a
    |__my_file.txt

dir_b
    |__my_file.txt
"""
from pathlib import Path

dir_a_my_file = Path("dir_a") / "my_file.txt"
dir_b = Path("dir_b")

# Act
dir_a_my_file.copy_into(dir_b)  # Success - dir_a/my_file.txt overwrites dir_b/my_file.txt

However, when a directory is copied into another directory (one which contains a sub-directory with the same name),
the copy operation fails and FileExistsError is raised:

"""
# Copying a directory into a directory, that contains a sub-directory with the same name #

Directory Structure:
dir_a
    |__my_dir

dir_b
    |__my_dir
"""
from pathlib import Path

dir_a_my_dir = Path("dir_a") / "my_dir"
dir_b = Path("dir_b")

# Act
dir_a_my_dir.copy_into(dir_b)  # Failure - FileExistsError is raised.
Problem

The behaviour of the copy_into() method in the file case (success) and in the directory case (failure) is inconsistent.
It is also inconsistent with how Linux (when using cp -r) handles this exact same case.

Expected Result

Instead of raising an exception, the copied directory should be merged with the existing one.

Fix Suggestion
  1. Add a default exist_ok=True parameter to copy_into().
    This parameter is already used in the Path.touch() and Path.mkdir() methods, and should be familiar to users.

  2. When a file is copied into a destination directory that already has a file with the same name:

    • If exist_ok=True, the copied file should overwrite the file at the destination directory.
      This is the already the current behaviour, so no additional changes are required.

    • If exist_ok=False, a FileExistsError exception will be raised. This is consistent with the behaviour of Path.touch().

  3. When a directory is copied into a destination directory that contains a sub-directory with the same name:

    • If exist_ok=True, the copied directory will be merged with the destination's sub-directory.
      This is consistent with the behaviour of copying in Linux.
    • If exist_ok=False, a FileExistsError exception will be raised. This is consistent with the behaviour of Path.mkdir().

Thank you.

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Linked PRs
  • gh-143058

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

首先定位 pathlib 的實作以及 Path.copy_into() 的測試,然後將其目前的檔案和目錄衝突行為與 Path.touch() 和 Path.mkdir() 進行比較。完成的條件是支援 exist_ok,遞迴目錄複製依指定方式合併或引發例外,且這兩種情況都有測試涵蓋;請注意,已連結的 PR gh-143058 已表明相關工作正在進行中。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
operating-systems
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
描述清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。