Bug ou comportamento indesejado?

Estou trabalhando na construção do pacote do Python 2.4.2 para a plataforma Maemo e uma das nossas missões nesse projeto é fazer com que os pacotes com o Python ocupem pouco espaço em disco. Essa missão vem do fato que a plataforma Maemo é projetada para dispositivos móveis que não costumam ser construídos com discos muito grande.

Para reduzir essa ocupação de espaço resolvemos distribuir apenas os módulos otimizados (.pyo) da biblioteca Python porque esses arquivos são menores que os seus equivalentes em código fonte (.py) que serão distribuídos em um pacote separado específico para desenvolvedores. Outra mudança que fizemos foi distribuir esses pacotes dentro de um arquivo .zip.

No entanto, descobrimos posteriormente que o FS do N770 já é comprimido e colocar os módulos dentro desse .zip se tornou desnecessário. Enquanto eu ‘tirava’ os módulos de dentro do ZIP eu esbarrei numa inconsistência no comportamento do CPython que vou ilustrar na seção abaixo:

  1. Primeiramente eu crio dois módulos compilados. Um deles com otimização e o outro sem e adiciono os mesmos dentro de um ZIP:
$ ls
modulo_c.pyc  modulo_o.pyo
$ zip modulos.zip modulo_o.pyo modulo_c.pyc
  adding: modulo_o.pyo (deflated 38%)
  adding: modulo_c.pyc (deflated 38%)
$ ls
modulo_c.pyc  modulo_o.pyo  modulos.zip
  1. Depois aciono o interpretador em modo normal (não-otimizado):
$ python2.4
>>> import modulo_c
modulo_c
>>> import modulo_o
ImportError: No module named modulo_o

Como puderam observar, o interpretador Python não procura arquivos com a extensão .pyo quando está em modo não-otimizado.

  1. Na seqüência eu aciono o interpretador em modo otimizado:
$ python2.4 -O
>>> import modulo_c
ImportError: No module named modulo_c
>>> import modulo_o
modulo_o

E o comportamento inverso pode ser observado. O interpretador também não procura módulos .pyc quando está em modo otimizado.

  1. Removo os módulos .pyc e .pyo para ficar com eles apenas dentro do Zip e repito os passos anteriores dizendo que o ‘modulos.zip’ agora faz parte do PYTHONPATH e deve servir de local para procura de módulos Python:
$ rm *.pyc *.pyo
$ ls
modulos.zip
$ PYTHONPATH=modulos.zip python2.4
>>> import modulo_c
modulo_c
>>> import modulo_o
modulo_o
$ PYTHONPATH=modulos.zip python2.4 -O
>>> import modulo_c
modulo_c
>>> import modulo_o
modulo_o

Aqui está a inconsistência. Utilizando o hook zipimport do Python ele procura por módulos .pyc e .pyo no PYTHONPATH. A única distinção que ele faz entre os dois modos é a de que no modo normal o interpretador procura na ordem “py->pyc->pyo” e no modo otimizado ele procura na ordem “py->pyo->pyc”.

Acho que essa inconsistência tem que ser eliminada e, em minha humilde opinião o comportamento do hook zipimport é mais adequado do que o do primeiro porque poderemos encontrar casos onde bibliotecas bytecode sejam fornecidas como .pyo e .pyc misturados (ok, eu sei que só renomear o arquivo já que o bytecode é o mesmo, mas não acho essa solução muito ‘elegante’).

Estou preparando um patch para deixar o comportamento do hook de importação padrão do Python funcione de maneira equivalente ao hook zipimport e vou submetê-lo para o projeto. Mas como esse patch tem uma solução baseada na minha visão eu gostaria de saber antes a opinião dos leitores: Qual dos 2 comportamentos deve permanecer? E, isso deve ser mudado?

Available for Amazon Prime