Por que o mmap do Python não funciona com arquivos grandes?

[Edit: este problema se aplica apenas a sistemas de 32 bits. Se o seu computador, seu sistema operacional e sua implementação em Python forem de 64 bits, os arquivos enormes do mmap-ing funcionarão de forma confiável e serão extremamente eficientes.]

Eu estou escrevendo um módulo que, entre outras coisas, permite acesso de leitura bit a bit aos arquivos. Os arquivos podem ser grandes (centenas de GB), então eu escrevi uma classe simples que me permite tratar o arquivo como uma string e esconde toda a busca e leitura.

Na época em que escrevi minha turma de invólucros eu não sabia sobre omódulo mmap. Ao ler a documentação do mmap eu pensei"ótimo - isso é exatamente o que eu precisava, vou pegar meu código e substituí-lo por um mmap. É provavelmente muito mais eficiente e é sempre bom excluir código."

O problema é que o mmap não funciona para arquivos grandes! Isso é muito surpreendente para mim, como eu pensei que talvez fosse a aplicação mais óbvia. Se o arquivo estiver acima de alguns gigabytes, recebo umEnvironmentError: [Errno 12] Cannot allocate memory. Isso só acontece com uma compilação Python de 32 bits, então parece que está ficando sem espaço de endereço, mas não consigo encontrar nenhuma documentação sobre isso.

Meu código é apenas

f = open('somelargefile', 'rb')
map = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

Então minha pergunta éestou faltando alguma coisa óbvia aqui? Existe uma maneira de obter o mmap para trabalhar portavelmente em arquivos grandes ou devo voltar para o meu wrapper de arquivo ingênuo?

Atualização: Parece haver uma sensação de que o mmap do Python deve ter as mesmas restrições que o mmap POSIX. Para expressar melhor minha frustração aqui está uma classe simples que tem uma pequena parte da funcionalidade do mmap.

import os

class Mmap(object):
    def __init__(self, f):
        """Initialise with a file object."""
        self.source = f

    def __getitem__(self, key):
        try:
            # A slice
            self.source.seek(key.start, os.SEEK_SET)
            return self.source.read(key.stop - key.start)
        except AttributeError:
            # single element
            self.source.seek(key, os.SEEK_SET)
            return self.source.read(1)

É somente leitura e não faz nada extravagante, mas eu posso fazer isso da mesma forma que com um mmap:

map2 = Mmap(f)
print map2[0:10]
print map2[10000000000:10000000010]

exceto que não há restrições no tamanho do arquivo. Não é muito difícil realmente ...

questionAnswers(8)

yourAnswerToTheQuestion