Experiência dos “Novos ganchos de importação PEP-302” do Python [fechados]


40

Eu sou um dos desenvolvedores do Ruby (CRuby). Estamos trabalhando no lançamento do Ruby 2.0 (planejado para lançamento em 2012 / fevereiro).

O Python possui "PEP302: Novos ganchos de importação" (2003):

Este PEP propõe adicionar um novo conjunto de ganchos de importação que ofereçam uma melhor personalização do mecanismo de importação do Python. Ao contrário do gancho de importação atual , um gancho de novo estilo pode ser injetado no esquema existente, permitindo um controle mais refinado de como os módulos são encontrados e como são carregados.

Estamos pensando em introduzir um recurso semelhante ao PEP302 no Ruby 2.0 (CRuby 2.0). Quero fazer uma proposta que possa convencer Matz. Atualmente, o CRuby pode carregar scripts apenas de sistemas de arquivos de maneira padrão.

Se você tem alguma experiência ou consideração sobre o PEP 302, compartilhe.

Exemplo:

  1. É uma ótima especificação. Não há necessidade de mudar isso.
  2. É quase bom, mas tem esse problema ...
  3. Se eu pudesse voltar para 2003, alteraria as especificações para ...

6
Uau, o próprio YARV, olá e bem-vindo aos programadores! ;) No Stack Exchange, nós realmente não gostamos de discussões abertas; adoramos resolver problemas específicos (leia rapidamente nossas Perguntas frequentes ) - o que eu acho que é por isso que sua pergunta foi encerrada no Stack Overflow e já possui um voto próximo aqui. Você deve tentar tornar isso um pouco mais específico - você tem uma preocupação específica com o PEP 302 que motivou essa pergunta?
yannis

4
Obrigado pelo seu comentário, Yannis. Eu acho que quero discutir sobre "arquitetura de software". O PEP302 parece uma estrutura poderosa e geral para estender seus próprios carregadores no interpretador python. No entanto, um recurso poderoso apresenta riscos como uso excessivo (gera códigos mágicos), impedindo a otimização do intérprete. Então, eu quero saber que essa estrutura de extensão é interessante ou não para usuários de python e desenvolvedores de intérpretes. Acredito que estudar história me ajudará a fazer boas especificações no Ruby 2.0.
Koichi Sasada

Obrigado modificando minha pergunta bastante. E me desculpe se esta pergunta não é preferível.
Koichi Sasada

Este é um exemplo fantástico de como uma pergunta que parece, superficialmente, falhar em nosso teste de "pesquisa de opinião", pode, no entanto, provar ter um valor incrível.
Ross Patterson

Respostas:


47

Sou o mantenedor do módulo runpy do Python e um dos mantenedores do sistema de importação atual. Embora nosso sistema de importação seja impressionantemente flexível, eu aconselho a não adotá-lo no atacado sem fazer alguns ajustes - devido a questões de compatibilidade com versões anteriores, existem várias coisas que são mais estranhas do que seriam necessárias.

Uma coisa que atrapalhou o PEP 302 em Python é quanto tempo levamos para converter o sistema principal de importação para usá-lo. Na maior parte de uma década, qualquer pessoa que faça algo complexo com ganchos de importação não consegue implementar duas partes: uma manipulando carregadores compatíveis com PEP 302 (como importações de zip) e uma segunda manipulando o mecanismo de importação padrão baseado em sistema de arquivos. É apenas no próximo 3.3 que o manuseio de carregadores PEP 302 também cuidará dos módulos importados através do mecanismo de importação padrão do sistema de arquivos. Tente não repetir esse erro, se puder evitá-lo.

O PEP 420 (implementado no Python 3.3) faz algumas adições ao protocolo para permitir que os importadores contribuam com partes para os pacotes de namespace. Ele também corrige um problema de nomenclatura na definição da API do Finder (substituindo efetivamente o "find_module" com o nome incorreto pelo "find_loader" mais preciso). Espero que tudo isso esteja documentado mais claramente na especificação do idioma no momento em que o 3.3rc1 for lançado em algumas semanas.

Outro problema notável é que a abordagem documentada especificamente no PEP 302 tem muito estado global do processo. Não nos siga nesse caminho - tente encapsular o estado em um modelo de objeto mais coerente, para que seja um pouco mais fácil importar seletivamente outros módulos (os módulos de extensão C são a proibição de tornar esse encapsulamento completamente eficaz, mas mesmo algum nível de encapsulamento pode ser útil).

O PEP 406 (http://www.python.org/dev/peps/pep-0406/) discute uma possível evolução compatível com versões anteriores da abordagem do Python com melhor encapsulamento de estado. Se você tiver um modelo de estado encapsulado desde o início, poderá definir suas APIs de acordo e evitar que importadores e carregadores acessem o estado global (ao invés de uma referência ao mecanismo ativo).

Outra peça que falta no PEP 302 é a capacidade de solicitar a um importador um iterador sobre os módulos fornecidos por esse importador (isso é necessário para coisas como utilitários de congelamento e utilitários de documentação automáticos que extraem documentos). Como é incrivelmente útil, é melhor padronizá-lo desde o início: http://docs.python.org/dev/library/pkgutil#pkgutil.iter_modules (provavelmente elevaremos isso para um valor formalmente especificado) API no Python 3.4)

E meu último comentário é que você deve examinar atentamente a divisão de responsabilidades entre o sistema de importação e os objetos do carregador. Em particular, considere dividir a API "load_module" em etapas separadas "init_module" e "exec_module". Isso deve permitir minimizar o grau em que os carregadores precisam interagir diretamente com o estado de importação.

O PEP 302 e o importlib são um excelente ponto de partida para um sistema de importação mais flexível, mas definitivamente cometemos erros que vale a pena evitar.


11
Eles não estão completamente terminado ainda, mas um esboço inicial dos docs sistema importação completa pode ser encontrada em docs.python.org/dev/reference/import
ncoghlan

11
python.org/dev/peps/pep-0451 é uma atualização do sistema de importação do Python para Python 3.4 que aborda muitos dos comentários de Brett e eu aqui.
Ncoghlan 03/03

28

Ao lado de ncoghlan, sou o outro mantenedor do sistema de importação do Python e o autor de sua implementação atual, importlib (http://docs.python.org/dev/py3k/library/importlib.html). Tudo o que Nick disse que eu concordo, então eu só quero adicionar algumas informações extras.

Primeiro, não confie muito no PEP 302 diretamente, mas observe o que o importlib fornece em termos de classes base abstratas etc. Para compatibilidade com versões anteriores, as coisas tinham que ser compatíveis com o PEP 302, mas eu tinha que adicionar algumas das minhas próprias APIs para finalizar o suporte à verdadeira flexibilidade.

Outro ponto importante é que você está dando aos desenvolvedores duas partes de flexibilidade. Uma é a capacidade de armazenar código de uma maneira que não seja apenas diretamente no sistema de arquivos como arquivos individuais (eu chamo isso de backend de armazenamento para importações), por exemplo, isso permite que o código viva em um arquivo zip, banco de dados sqlite, etc. O outro suporte é permitir que o controle pré ou pós-processe o código de alguma maneira, por exemplo, Quixote (https://www.mems-exchange.org/software/quixote/) e seu uso alternativo de literais de string não atribuídos a uma variável seria muito mais fácil de suportar.

Enquanto o último raramente é necessário, o primeiro é onde você precisa se preocupar com o suporte. E é aí que você acaba redefinindo praticamente as APIs de interação do sistema de arquivos. Como algumas pessoas precisam de ativos armazenados como arquivos com seu código, é necessário fornecer uma boa maneira de ler arquivos, descobrir arquivos etc. Ainda precisamos implementar a parte da API para descobrir quais arquivos de dados estão disponíveis, listá-los etc. .

Mas você também precisa de APIs específicas do código. Como Nick mencionou, você acaba precisando de APIs para descobrir quais módulos um pacote contém etc. que não são específicos de arquivos. Existe essa estranha dualidade de ter APIs para lidar com módulos nos quais você extraiu o conceito de arquivos, mas acaba precisando fornecer APIs para acessar dados de ativos semelhantes a arquivos. E assim que você tenta implementar uma em relação à outra para evitar duplicação, as águas ficam realmente escuras (ou seja, as pessoas acabam confiando na estrutura esperada do caminho do arquivo etc.) sem prestar atenção ao fato de que o caminho pode não ser um caminho verdadeiro porque é para um arquivo zip que contém código e não apenas um arquivo). IOW, você precisará implementar duas APIs semelhantes, mas será melhor a longo prazo.

Como Nick disse, nossa solução é um bom ponto de partida, mas não é assim que eu faria hoje se estivesse projetando a API do zero.


-1

O PEP 302 permite conectar-se ao mecanismo de importação Python, o que significa que você pode importar código de outras fontes, como bancos de dados, arquivos zip e assim por diante.

Na implementação de importações do Python, há um longo histórico de complexidade que em breve será simplificado pela introdução de uma implementação de importação do Python.

Eu deveria aconselhar a pensar muito sobre os casos de canto. É provável que você obtenha uma implementação útil.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.