Path.copy: copie arquivos e pastas com segurança

Publicado em: 12/10/2026
Tempo de leitura: 6 minutos
Computador com código representando cópia de arquivos com Path.copy no Python

Path.copy() amplia a API orientada a objetos do pathlib para copiar arquivos e árvores de diretórios sem sair da abstração de caminhos. Em vez de converter objetos Path para strings e alternar entre vários módulos, você pode manter a lógica de navegação, validação e cópia em uma interface única. Isso torna scripts de backup, ferramentas de build, instaladores, migrações e rotinas de organização de arquivos mais legíveis.

Este guia explica o comportamento esperado, os cuidados com sobrescrita, links simbólicos, metadados, permissões, erros parciais e testes. O foco não é apenas a sintaxe, mas como usar a operação de forma previsível em projetos reais.

O que Path.copy faz

A ideia central é copiar o caminho atual para um destino informado. Quando a origem é um arquivo, o conteúdo é replicado no destino. Quando é um diretório, a operação pode percorrer a árvore e criar a estrutura correspondente. A API reduz código cerimonial e deixa claro que a ação pertence ao próprio caminho.

Mesmo com uma interface simples, copiar arquivos envolve decisões importantes: o destino existe, deve ser substituído, links devem ser seguidos, permissões precisam ser preservadas e o sistema de arquivos aceita os mesmos recursos? Essas perguntas precisam ser respondidas antes de usar a função em produção.

Exemplo básico

from pathlib import Path

origem = Path("dados/relatorio.csv")
destino = Path("backup/relatorio.csv")

destino.parent.mkdir(parents=True, exist_ok=True)
resultado = origem.copy(destino)
print(resultado)

Crie o diretório pai explicitamente quando necessário. Isso evita depender de comportamento implícito e facilita a validação. Guarde o caminho retornado para registrar logs, executar verificações ou continuar o processamento.

Copiando diretórios

Para árvores de diretórios, confirme se a versão do Python e o sistema suportam o comportamento desejado. Uma cópia recursiva deve preservar a estrutura, mas não deve ser tratada como transação atômica. Se a operação falhar no meio, parte dos arquivos pode ter sido criada. Portanto, use um diretório temporário e faça a troca final somente após verificar o resultado quando a consistência for importante.

from pathlib import Path
import tempfile

origem = Path("site")
destino = Path("dist/site")

with tempfile.TemporaryDirectory(dir=destino.parent) as temp:
    temporario = Path(temp) / "site"
    origem.copy(temporario)
    if destino.exists():
        raise FileExistsError(destino)
    temporario.replace(destino)

Esse padrão reduz o risco de deixar um destino oficialmente válido, porém incompleto.

Sobrescrita e conflitos

Não presuma que o destino será substituído. Verifique a documentação da versão usada e implemente uma política explícita. Em backups, normalmente é melhor gerar nomes versionados. Em builds reproduzíveis, pode ser aceitável remover uma pasta anterior após confirmar que ela pertence ao processo atual. Em dados do usuário, sobrescrita silenciosa deve ser evitada.

def copiar_sem_substituir(origem: Path, destino: Path) -> Path:
    if destino.exists():
        raise FileExistsError(f"Destino já existe: {destino}")
    destino.parent.mkdir(parents=True, exist_ok=True)
    return origem.copy(destino)

Evite o padrão de testar e copiar em ambientes concorrentes sem proteção, porque outro processo pode criar o destino entre as duas operações. Quando houver concorrência real, use diretórios exclusivos, locks ou nomes aleatórios.

Links simbólicos exigem uma decisão de segurança. Seguir o link copia o conteúdo apontado; preservar o link mantém a referência. Em entradas não confiáveis, seguir links pode levar a arquivos fora da árvore esperada. Resolva caminhos com cuidado, imponha uma raiz permitida e rejeite destinos que escapem dela.

raiz = Path("entrada").resolve()
origem = Path("entrada/item").resolve()
if raiz not in origem.parents and origem != raiz:
    raise ValueError("Origem fora da raiz permitida")

Essa checagem ajuda, mas condições de corrida ainda podem existir em sistemas onde links mudam durante a operação.

Metadados e permissões

Conteúdo, timestamps, modo de acesso, ACLs, atributos estendidos e proprietário não são a mesma coisa. Uma cópia pode preservar alguns metadados e perder outros, especialmente entre sistemas de arquivos diferentes. Se a fidelidade for crítica, teste no ambiente alvo e valide explicitamente os atributos importantes.

Também considere o princípio do menor privilégio. Um arquivo copiado não deve herdar permissões mais amplas do diretório de destino sem revisão. Para segredos, ajuste o modo depois da cópia e nunca registre o conteúdo em logs.

Tratamento de erros

Capture erros específicos como FileNotFoundError, PermissionError, FileExistsError e OSError. Registre origem, destino e etapa, mas evite expor caminhos sensíveis a usuários finais.

try:
    origem.copy(destino)
except FileNotFoundError:
    print("A origem não existe")
except PermissionError:
    print("Permissão insuficiente")
except OSError as erro:
    print(f"Falha no sistema de arquivos: {erro}")

Para lotes, decida se um erro interrompe tudo ou se os demais itens continuam. Produza um relatório final com sucessos e falhas.

Desempenho

O desempenho depende do tamanho dos arquivos, latência do disco, cache, rede e implementação do sistema operacional. Evite ler todo o conteúdo em memória apenas para copiar. Para grandes volumes, meça throughput e espaço livre antes de iniciar. Em destinos remotos, implemente retentativas apenas para erros transitórios e nunca repita cegamente uma operação parcialmente concluída.

Validação após a cópia

Para dados comuns, tamanho e existência podem ser suficientes. Para artefatos críticos, calcule hashes na origem e no destino. Isso custa I/O adicional, mas detecta corrupção ou cópias incompletas.

import hashlib

def sha256(caminho: Path) -> str:
    digest = hashlib.sha256()
    with caminho.open("rb") as arquivo:
        for bloco in iter(lambda: arquivo.read(1024 * 1024), b""):
            digest.update(bloco)
    return digest.hexdigest()

Compatibilidade entre versões

Antes de adotar Path.copy, confirme a versão mínima do Python do projeto. Bibliotecas distribuídas para ambientes antigos podem oferecer um fallback com shutil. Centralize essa compatibilidade em uma função para não espalhar condicionais pelo código.

def copiar(origem: Path, destino: Path) -> Path:
    if hasattr(origem, "copy"):
        return origem.copy(destino)
    import shutil
    if origem.is_dir():
        return Path(shutil.copytree(origem, destino))
    return Path(shutil.copy2(origem, destino))

Testes recomendados

Teste arquivo pequeno, arquivo vazio, diretório aninhado, destino existente, falta de permissão, link simbólico, nomes Unicode, caminhos longos, disco cheio e interrupção durante a cópia. Use tempfile.TemporaryDirectory para isolar os testes. Em integração, execute nos sistemas operacionais suportados.

Boas práticas

Valide a origem, crie o pai do destino, defina uma política de sobrescrita, controle links simbólicos, trate cópias recursivas como não atômicas, verifique espaço livre, registre resultados e valide arquivos críticos. Não aceite caminhos arbitrários de usuários sem limitar a raiz permitida.

Veja também pathlib no Python, shutil no Python, arquivos no Python e tratamento de erros. Consulte a documentação oficial do pathlib e a documentação do shutil.

Conclusão

Path.copy torna operações de cópia mais coerentes com o estilo moderno do pathlib. A simplicidade da chamada não elimina decisões sobre segurança, consistência, metadados e compatibilidade. Encapsule a política de cópia, teste em múltiplas plataformas e use validação proporcional à importância dos dados.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código em monitor representando acesso a memória nativa com ctypes.memoryview_at no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ctypes.memoryview_at: acesse memória sem cópias

    Aprenda ctypes.memoryview_at no Python para acessar memória nativa sem cópias, validar ponteiros e evitar erros perigosos.

    Ler mais

    Tempo de leitura: 7 minutos
    12/10/2026
    Código Python em tela representando EnumDict e enumerações avançadas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    EnumDict: personalize Enums com validação

    Aprenda EnumDict no Python para personalizar EnumType, validar membros e criar enumerações avançadas com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    11/10/2026
    Rack de servidores representando balanceamento de conexões com SO_REUSEPORT_LB no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    SO_REUSEPORT_LB: distribua conexões entre workers

    Aprenda SO_REUSEPORT_LB no Python para distribuir conexões entre múltiplos workers com segurança, testes e portabilidade.

    Ler mais

    Tempo de leitura: 6 minutos
    11/10/2026
    Código Python assíncrono em notebook para inspect.markcoroutinefunction
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    markcoroutinefunction: identifique wrappers async

    Aprenda inspect.markcoroutinefunction no Python para identificar wrappers assíncronos, integrar frameworks e evitar detecção incorreta de corrotinas.

    Ler mais

    Tempo de leitura: 6 minutos
    10/10/2026
    Código Python para percorrer pastas e arquivos com Path.walk
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    Path.walk: percorra diretórios com segurança

    Aprenda Path.walk no Python para percorrer diretórios, filtrar arquivos, tratar erros e controlar a travessia com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    10/10/2026
    Depuração de processo Python em terminal com código
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p: depure processos Python em execução

    Aprenda a anexar o pdb a um processo Python em execução, inspecionar pilhas e diagnosticar travamentos com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    09/10/2026