python / python/cpython

Improve `tarfile` streaming mode to handle very large archives

Aberta
#139,960 3 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

stdlib type-feature
Linguagem predominante
Python
Estrelas
77.2k
Forks
36k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

Bug report

Bug description:

I am trying to use tarfile to write very large archives, and the process is being killed by the OOM killer. I would expect+want to be able to use it in streaming mode (write an unlimited number of files) like the standard tar command line utility supports by default.

Reproduction case attached.

import gc
import io
import os
import psutil
import tarfile

if __name__ == "__main__":
    t = tarfile.open("a.tar", mode="w") # default compresslevel 9
    for i in range(1,100_000_000):
        if i % 10_000 == 0:
            gc.collect()
            process = psutil.Process(os.getpid())
            mem_info = process.memory_info()
            mem = mem_info.rss
            print(f"Iteration {i}, memory usage: {mem}")

        bs = (" "*1000 + str(i)).encode('utf8')
        with io.BytesIO(bs) as file:
            tarinfo = tarfile.TarInfo(name="cool_files/{i}.txt")
            tarinfo.size = len(bs)
            t.addfile(tarinfo, file)

The memory usage increases without bound because the list of this line in addfile():

self.members.append(tarinfo)

I'm not sure what the use-case is for this line. In write-only mode, it does not seem useful. Maybe mixed read/write? But in general it does not seem correct to assume you can fit all the tarinfo's in memory.

Edit: As a workaround, I'm setting t.members=[] manually.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece pela implementação de tarfile em torno de TarFile.addfile() e da linha self.members.append(tarinfo), usando a reprodução relatada para observar o crescimento da memória. Determine o comportamento pretendido para o modo somente gravação ou streaming e, em seguida, verifique se a gravação de arquivos muito grandes mantém o uso de memória limitado sem afetar outros casos de uso de tarfile.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
backend
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Razoavelmente clara
Facilidade para iniciantes
45/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.