quinta-feira, 12 de maio de 2011

Código obsoleto entre 2.7 e 3.2

Discussões recentes na lista python-dev trouxe à tona as determinações de obsolência de código entre os desenvolvedores trabalhando com as mudanças da versão 2.7 para 3.2. Graças a essa discussão, a equipe de desenvolvedores modificou as determinações de obsolência de código, levando em conta que usuários de Python migrarão diretamente da versão 2.7 para 3.x, sem passar por qualquer versão intermediária.

Perspectiva

A linguagem Python tem um grande compromisso com compatibilidade de versões anteriores. Nenhuma alteração é permitida sem antes obedecer orientações de compatibilidade, o que, essencialmente, diz que programas sem erros de código não devem se tornar incorretos com o uso de novas versões de Python. No entanto, isso nem sempre é possível, por exemplo quando a API tem problemas que devem ser modificados por novas versões. Nesse caso, Python segue uma política de obsolência baseada num período de transição anual, no qual recursos considerados obsoletos são formalmente removidos. No período entre transições, um aviso de obsolência é dado a todos os desenvolvedores, visando uma atualização de código. Informações sobre as determinações de obsolência estão documentadas na PEP 5. Como modificações só podem ser feitas em novos releases, e há um intervalo de 18 meses entre releases, isto quer dizer que é normal um período de obsolência de um release.

A única exceção as essas normas é Python 3. A mudança de versão de Python 2 para 3 foi especificamente planejada para englobar mudanças que possam não ser compatíveis com versões antigas, permitindo aos desenvolvedores de Python corrigir defeitos que não poderiam ser corrigidos com a atual normativa. Por exemplo, transformar strings em Unicode, e retornar iterators ao invés de listas.

Linhas de Desenvolvimento Paralelas

Sabendo-se que a transição para Python 3 demoraria algum tempo, algumas estimativas apontam 5 anos, ficou claro que haveria um bom número de desenvolvimento em paralelo das versões 2 e 3.

Como o release final de Python dois é a versão 2.7, foi acordado que o período de manutenção seria estendido por um bom tempo. No final, programadores que querem atualizar-se com uma versão nova de Python, terão de mudar diretamente para Python 3.

Mas, existem alguns problemas ...

Obsolências surpresa

Em uma discussão da python-dev, um participante apontou para o fato de que uma função específica da API C, PyCObject_AsVoidPtr, foi removida com um aviso prévio curto demais. Mas as determinações de obsolência deveriam evitar tais tipos de problemas! O que poderia ter acontecido?

A alteração fazia parte de uma mudança maior, da API antiga (PyCObject) para uma nova e melhor (PyCapsule). O problema é PyCObject é a padrão, e na realidade, a única API disponível em Python 2.6. Foi considerada obsoleta em Python 2.7. Em Python 3.2, essa API não existe, e a nova PyCapsule deve ser usada. Isso faz com que o período de obsolência desde o lançamento de Python 2.7 (Julho de 2010) até Python 3.2 (Fevereiro de 2011), cerca de sete meses. Bem aquém do tempo necessário de 12 meses, fazendo com que seja difícil para desenvolvedores mantenham um número razoável de versões.

Para alguém mudando de 3.0 para 3.1 e para 3.2, as obsolências não acarretam problemas. Python 3.1 foi lançado em Março de 2010, com a obsolência, e no ciclo 3.x, o tempo de 12 meses foi cumprido. No entanto, este não é o caminho escolhido por muitos: normalmente, desenvolvedores vão da versão 2.7 para o lançamento mais recente de 3.x, no caso 3.2, o que resulta em problemas. Esta nunca foi a ideia da python-dev, mas a PEP 5 não foi escrita para desenvolvimento de versões paralelas de Python, ambas sob desenvolvimento ativo.

O que fazer?

Mesmo que o caso PyCObject/PyCapsule da API seja mesmo um problema, não é impossível de contorná-lo. No entanto, pelo menos um desenvolvedor da python-dev teve dificuldades para lidar com o problema, e isto não pode acontecer.

No caso específico do PyCObject/PyCapsule, o problema já existe e não há muito o que se fazer. Reintroduzir PyCObject não era uma opção viável, o que acarretaria uma série de incompatibilidades. No entanto, o consenso geral era que seria possível, ainda que enfadonho, escrever código, adaptando a API atual. Na verdade, em Python 3.1, PyCObject foi escrito encapsulando a API PyCapsule. Foi sugerido que se alguém necessitasse da implementação, ela poderia ser extraída para uso de código externo. Além disso, foi acordado que uma PEP "retroativa" relatando a mudança deveria ser escrita, descrevendo as razões da mudança e documentar recursos que podem auxiliar desenvolvedores.

Em termos gerais, a equipe de desenvolvedores Python já está consciente do problema e vai trabalhar para evitar que isso ocorra novamente. Guido deu sua opinião sobre a situação e sugeriu que Python 3 deve ser conservador quanto a obsolências no momento. No mínimo, API obsoletas devem ser mantidas por um período maior, antes de serem removidas, permitindo que desenvolvedores possam migrar da versão 2.7 sem problemas.

Indiretamente, a discussão trouxe à tona o tópico de como comunicar alterações de maneira mais eficiente e oportuna para uma audiência maior, - uma das razões da existência deste blog.

Qual o significado disso tudo?

Em primeiro lugar, significa que os desenvolvedores de Python nem sempre acertam. Ninguém teve a intenção de tornar a vida dos programadores mais difícil; o que ocorreu foi uma falha que não foi detectada a tempo.

Além disso, consertar o problema pode acarretar mais problemas do que solucioná-los, fazendo com que a API PyCObject não seja reintegrada. A reintegração poderia ajudar desenvolvedores que foram pegos pelo problema, mas de maneira geral isso faria com que problemas de compatibilidade se tornassem mais complexos. Entretanto, temos de aceitar o problema e continuar trabalhando. Aprendemos a lição, e não cometeremos o mesmo erro da próxima vez.

Isso mostra que a equipe de desenvolvedores Python quer saber a opinião dos usuários. Compatibilidade é muito importante, e todos os esforços são feitos para tornar indolor a transição de versões. Em particular, desenvolvedores de bibliotecas devem ser capazes de manter múltiplas versões de Python com um nível de trabalho razoável.

E por fim, desenvolvedores ainda não abandonaram a versão 2.7. Mesmo que novos recursos não sejam adicionados a essa versão, e como não haverá versão 2.8, opiniões de pessoas ainda usando 2.7 é importante. Ter certeza de que usuários possam migrar para versões 3.x assim que se sentirem prontos para tal, é vital para toda a comunidade Python.

Nenhum comentário:

Postar um comentário