1
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
2
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
3
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
4
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
5
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
6
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
7
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
8
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
9
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini2...
10
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
11
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
12
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
13
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
14
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
15
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
16
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
17
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
18
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
19
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
20
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
21
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
22
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
23
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
24
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
25
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
26
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
27
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
28
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
29
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
30
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
31
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
32
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
33
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
34
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
35
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
36
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
37
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
38
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
39
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
40
Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3
2013-10-02 – Danilo J. S. Bellini – @danilobellini...
Próximos SlideShares
Carregando em…5
×

(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3

631 visualizações

Publicada em

Apresentação realizada durante a PythonBrasil[9]. Segue abaixo a descrição da palestra:

Mudanças na especificação da linguagem fizeram o Python 3 incompatível com parte do código escrito para o Python 2.
Algumas dessas incompatibilidades podem ser facilmente resolvidas através de traduções, sejam elas automáticas ou não.
Porém, muitas dessas traduções trazem consigo uma incompatibilidade com a versão de origem do código (o Python 2, neste caso), o que nem sempre é desejável.

É possível manter um único código compatível com o ambos o Python 2 e 3?
Esta atividade se propõe a responder essa pergunta, e enfatizará os problemas e soluções que levaram à elaboração do módulo lazy_compat da AudioLazy (e.g. metaclasses, arredondamento de ponto flutuante).

Publicada em: Tecnologia
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
631
No SlideShare
0
A partir de incorporações
0
Número de incorporações
14
Ações
Compartilhamentos
0
Downloads
6
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3

  1. 1. 1 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Compatibilidade entreCompatibilidade entre Python 2 e 3Python 2 e 3 Como portar seu código em Python 2.x para o Python 3.x sem torná-lo incompatível com o Python 2.x? Com base na história do pacote AudioLazy
  2. 2. 2 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Por quê?Por quê? ● Versões futuras do PythonVersões futuras do Python ● Ampliar o público-alvo de seu projetoAmpliar o público-alvo de seu projeto – AudioLazyAudioLazy ● https://pypi.python.org/pypi/audiolazy/https://pypi.python.org/pypi/audiolazy/ ● Pressão social e tecnofílicos!Pressão social e tecnofílicos! – Software para uso científicoSoftware para uso científico ● NumPyNumPy ● MatPlotLibMatPlotLib ● SciPySciPy – Notícias recentesNotícias recentes ● Flask!Flask! TODOS já são compatíveis com o Python 3.x! E outros 2800+ pacotes no PyPI... Python 2.x is the status quo, Python 3.x is the present and future of the language. www.python.org
  3. 3. 3 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Valores coletados dia 2013-10-02 Alguns númerosAlguns números Compatibilidade entre Python 2.7 e outras versões Compatibilidade entre Python 3 e outras versões
  4. 4. 4 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Por onde começarPor onde começar ● Suíte de testesSuíte de testes ● Conhecimento sobreConhecimento sobre as diferenças entreas diferenças entre versõesversões – Ler, estudarLer, estudar – Fuçar, brincar,Fuçar, brincar, remoer, torturar aremoer, torturar a linguagemlinguagem ● Outras ferramentas eOutras ferramentas e pacotespacotes – Já solucionaram o mesmoJá solucionaram o mesmo problema? Como?problema? Como? – Pacotes de auxílio àPacotes de auxílio à compatibilizaçãocompatibilização – Dependências funcionamDependências funcionam em quais versões doem quais versões do Python?Python? ● Diminuir restriçõesDiminuir restrições
  5. 5. 5 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Parte 1Parte 1 Tipos de diferençasTipos de diferenças
  6. 6. 6 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Nomes e localizaçõesNomes e localizações import Tkinter master = Tkinter.Tk() master.mainloop() import Tkinter master = Tkinter.Tk() master.mainloop() import tkinter master = tkinter.Tk() master.mainloop() import tkinter master = tkinter.Tk() master.mainloop() Apenas Python 2Apenas Python 2 Apenas Python 3Apenas Python 3 Traceback (most recent call last): [...] ImportError: No module named Tkinter Traceback (most recent call last): [...] ImportError: No module named Tkinter Rodando no Python 3Rodando no Python 3 Rodando no Python 2Rodando no Python 2 Traceback (most recent call last): [...] ImportError: No module named tkinter Traceback (most recent call last): [...] ImportError: No module named tkinter
  7. 7. 7 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Nomes e localizaçõesNomes e localizações com try...exceptcom try...except try: import tkinter except ImportError: import Tkinter as tkinter master = tkinter.Tk() master.mainloop() try: import tkinter except ImportError: import Tkinter as tkinter master = tkinter.Tk() master.mainloop() ● Nome únicoNome único – ““as” no importas” no import – AtribuiçãoAtribuição ● Há critérios para uso doHá critérios para uso do nome?nome? – PEP8PEP8 – Nome no Python 3Nome no Python 3 ● Versões futurasVersões futuras – Nome no Python 2Nome no Python 2 ● Atual hábitoAtual hábito ● Ausente no Python 3Ausente no Python 3 Quais nomes foram “trocados”? Quais nomes foram “trocados”? Documentação para Documentação para desenvolvedores! desenvolvedores!
  8. 8. 8 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Módulo future_builtinsMódulo future_builtins In [1]: import future_builtins In [2]: dir(future_builtins) Out[2]: ['__doc__', '__file__', '__name__', '__package__', 'ascii', 'filter', 'hex', 'map', 'oct', 'zip'] In [1]: import future_builtins In [2]: dir(future_builtins) Out[2]: ['__doc__', '__file__', '__name__', '__package__', 'ascii', 'filter', 'hex', 'map', 'oct', 'zip'] Fazer zip/map/filter do Python 2 funcionar comoFazer zip/map/filter do Python 2 funcionar como no Python 3 (módulo existe somente no Python 2)no Python 3 (módulo existe somente no Python 2) try: from future_builtins import * except ImportError: pass # Python 3 try: from future_builtins import * except ImportError: pass # Python 3
  9. 9. 9 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães ““Módulo” __future__Módulo” __future__ In [1]: import __future__ In [2]: dir(__future__) Out[2]: [ ... , 'absolute_import', 'all_feature_names', 'division', 'generators', 'nested_scopes', 'print_function', 'unicode_literals', 'with_statement'] In [1]: import __future__ In [2]: dir(__future__) Out[2]: [ ... , 'absolute_import', 'all_feature_names', 'division', 'generators', 'nested_scopes', 'print_function', 'unicode_literals', 'with_statement'] ● Linha inicial de seu códigoLinha inicial de seu código – Importar antes de outros importsImportar antes de outros imports ● Existe no Python 2 e 3Existe no Python 2 e 3
  10. 10. 10 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Nomes e localizaçõesNomes e localizações com verificação préviacom verificação prévia ● sys.version_infosys.version_info ● sys.modulessys.modules import sys PYTHON2 = sys.version_info.major == 2 if PYTHON2: builtins = sys.modules["__builtin__"] else: import builtins import sys PYTHON2 = sys.version_info.major == 2 if PYTHON2: builtins = sys.modules["__builtin__"] else: import builtins
  11. 11. 11 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Módulo sysMódulo sys In [1]: import sys In [2]: sys.version_info Out[2]: sys.version_info(major=3, minor=2, micro=4, releaselevel='final', serial=0) In [3]: sys.version_info >= (3, 2) Out[3]: True In [4]: sys.version_info >= (3, 3) Out[4]: False In [5]: sys.version Out[5]: '3.2.4 (default, May 8 2013, 20:55:18) n[GCC 4.7.3]' In [1]: import sys In [2]: sys.version_info Out[2]: sys.version_info(major=3, minor=2, micro=4, releaselevel='final', serial=0) In [3]: sys.version_info >= (3, 2) Out[3]: True In [4]: sys.version_info >= (3, 3) Out[4]: False In [5]: sys.version Out[5]: '3.2.4 (default, May 8 2013, 20:55:18) n[GCC 4.7.3]'
  12. 12. 12 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Nomes e localizaçõesNomes e localizações com getattrcom getattr ● Funções são objetosFunções são objetos ● Análogo ao método “get” de dicionáriosAnálogo ao método “get” de dicionários import itertools xzip = getattr(itertools, "izip", zip) xmap = getattr(itertools, "imap", map) xfilter = getattr(itertools, "ifilter", filter) # Usando o builtins visto anteriormente xrange = getattr(builtins, "xrange", range) import itertools xzip = getattr(itertools, "izip", zip) xmap = getattr(itertools, "imap", map) xfilter = getattr(itertools, "ifilter", filter) # Usando o builtins visto anteriormente xrange = getattr(builtins, "xrange", range)
  13. 13. 13 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Monkeypatch / MockMonkeypatch / Mock ● Usando getattr e atribuiçõesUsando getattr e atribuições ● Compatibilizar código de terceiros sem mudá-losCompatibilizar código de terceiros sem mudá-los ● Nem sempre é possível (tipos básicos)Nem sempre é possível (tipos básicos) – e.g. Método to_bytes do int (apenas Python 3)e.g. Método to_bytes do int (apenas Python 3) import operator operator.div = getattr(operator, "div", operator.truediv) import operator operator.div = getattr(operator, "div", operator.truediv) In [1]: (317215).to_bytes(5, "big") Out[1]: b'x00x00x04xd7x1f' In [1]: (317215).to_bytes(5, "big") Out[1]: b'x00x00x04xd7x1f'
  14. 14. 14 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Funções e outros objetosFunções e outros objetos ausentesausentes ● ReconstruirReconstruir ● Criar pela primeira vezCriar pela primeira vez – e.g. itertools.accumulatee.g. itertools.accumulate ● audiolazy.accumulateaudiolazy.accumulate from functools import wraps @wraps(range) def orange(*args, **kwargs): return list(range(*args, **kwargs)) from functools import wraps @wraps(range) def orange(*args, **kwargs): return list(range(*args, **kwargs))
  15. 15. 15 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Métodos ausentesMétodos ausentes ● Iteração sobre dicionáriosIteração sobre dicionários ● Iterável VS IteradorIterável VS Iterador – Gotcha!Gotcha! def iteritems(dictionary): try: return getattr(dictionary, "iteritems")() except AttributeError: return iter(getattr(dictionary, "items")()) def iteritems(dictionary): try: return getattr(dictionary, "iteritems")() except AttributeError: return iter(getattr(dictionary, "items")())
  16. 16. 16 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães str / intstr / int no Python 3no Python 3 ● String?String? – str no Python 3str no Python 3 – (unicode, str) no Python 2(unicode, str) no Python 2 ● builtins.basestringbuiltins.basestring ● Inteiro?Inteiro? – int no Python 3int no Python 3 – (long, int) no Python 2(long, int) no Python 2 INT_TYPES = (int, getattr(builtins, "long", None)) if PYTHON2 else (int,) print(isinstance(something_here, INT_TYPES)) INT_TYPES = (int, getattr(builtins, "long", None)) if PYTHON2 else (int,) print(isinstance(something_here, INT_TYPES)) Utilização com Utilização comisinstance isinstance
  17. 17. 17 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães InternalidadesInternalidades ● Iteradores (e geradores)Iteradores (e geradores) – Método next no Python 2Método next no Python 2 – Método __next__ no Python 3Método __next__ no Python 3 ● Avaliação “if obj:” segue um método de objAvaliação “if obj:” segue um método de obj – __nonzero__ no Python 2__nonzero__ no Python 2 – __bool__ no Python 3__bool__ no Python 3 ● Função do método (“unbound”)Função do método (“unbound”) – Python 2Python 2 ● classe.metodo.im_funcclasse.metodo.im_func ● objeto.metodo.im_funcobjeto.metodo.im_func – Python 3Python 3 ● classe.metodoclasse.metodo ● objeto.metodo.__func__objeto.metodo.__func__
  18. 18. 18 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Parte 2Parte 2 TestesTestes
  19. 19. 19 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães TestesTestes ● AutomatizadosAutomatizados – py.testpy.test – nosenose – unittestunittest – doctestdoctest ● Cobertura de códigoCobertura de código – ConfiabilidadeConfiabilidade – DependênciasDependências ● skipskip ● xfailxfail ● CompatibilizarCompatibilizar dependênciadependência Testes passandoTestes passando Testes falhandoTestes falhando
  20. 20. 20 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Skip automático comSkip automático com py.testpy.test import pytest def skipper(msg="There's something not supported " "in this environment"): def skip(*args, **kwargs): pytest.skip(msg.format(*args, **kwargs)) return skip operator.div = getattr(operator, "div", skipper("There's no " "operator.div")) import pytest def skipper(msg="There's something not supported " "in this environment"): def skip(*args, **kwargs): pytest.skip(msg.format(*args, **kwargs)) return skip operator.div = getattr(operator, "div", skipper("There's no " "operator.div"))
  21. 21. 21 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães toxtox [tox] envlist = py26,py27 [testenv] deps=pytest commands=py.test [tox] envlist = py26,py27 [testenv] deps=pytest commands=py.test ● ““Standardize testing in Python”Standardize testing in Python” ● tox.initox.ini
  22. 22. 22 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Parte 3Parte 3 Diferenças importantesDiferenças importantes !
  23. 23. 23 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães MetaclassesMetaclasses ● Classe cujas instâncias são classesClasse cujas instâncias são classes ● Sintaxe diferenciada no Python 2 e 3Sintaxe diferenciada no Python 2 e 3 # Python 3 bases = (object,) MyMeta = type class A(*bases, metaclass=MyMeta): pass # Python 2 class A(*bases): __metaclass__ = MyMeta # Python 3 bases = (object,) MyMeta = type class A(*bases, metaclass=MyMeta): pass # Python 2 class A(*bases): __metaclass__ = MyMeta
  24. 24. 24 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães MetaclassesMetaclasses ● Solução padrão:Solução padrão: – Criar uma classeCriar uma classe vazia usando avazia usando a metaclasse, e colocá-metaclasse, e colocá- la junto às basesla junto às bases ● Problemas:Problemas: – Construtor da classeConstrutor da classe pode falharpode falhar ● Solução alternativaSolução alternativa – Metaclasse falsaMetaclasse falsa ● Única base da novaÚnica base da nova classeclasse – Construtor daConstrutor da metaclasse com 2metaclasse com 2 comportamentoscomportamentos ● Antes da obtenção doAntes da obtenção do dicionário da classedicionário da classe ● Depois (realDepois (real instanciação)instanciação) – Função audiolazy.metaFunção audiolazy.meta
  25. 25. 25 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães >>> class BadMeta(type): ... def __new__(mcls, name, bases, namespace): ... if "bad" not in namespace: ... raise Exception("Oops, not bad enough") ... value = len(name) ... def really_bad(self): ... return self.bad() * value ... namespace["really_bad"] = really_bad ... return super(BadMeta, mcls).__new__(mcls, name, bases, ... namespace) ... >>> class Bady(meta(object, metaclass=BadMeta)): ... def bad(self): ... return "HUA " ... >>> class BadGuy(Bady): ... def bad(self): ... return "R" ... >>> issubclass(BadGuy, Bady) True >>> Bady().really_bad() # value = 4 'HUA HUA HUA HUA ' >>> BadGuy().really_bad() # value = 6 'RRRRRR' >>> class BadMeta(type): ... def __new__(mcls, name, bases, namespace): ... if "bad" not in namespace: ... raise Exception("Oops, not bad enough") ... value = len(name) ... def really_bad(self): ... return self.bad() * value ... namespace["really_bad"] = really_bad ... return super(BadMeta, mcls).__new__(mcls, name, bases, ... namespace) ... >>> class Bady(meta(object, metaclass=BadMeta)): ... def bad(self): ... return "HUA " ... >>> class BadGuy(Bady): ... def bad(self): ... return "R" ... >>> issubclass(BadGuy, Bady) True >>> Bady().really_bad() # value = 4 'HUA HUA HUA HUA ' >>> BadGuy().really_bad() # value = 6 'RRRRRR'
  26. 26. 26 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Função “meta”Função “meta” def meta(*bases, **kwargs): metaclass = kwargs.get("metaclass", type) if not bases: bases = (object,) class NewMeta(type): def __new__(mcls, name, mbases, namespace): if name: return metaclass.__new__(metaclass, name, Bases, namespace) return super(NewMeta, mcls).__new__(mcls, "", mbases, {}) return NewMeta("", tuple(), {}) def meta(*bases, **kwargs): metaclass = kwargs.get("metaclass", type) if not bases: bases = (object,) class NewMeta(type): def __new__(mcls, name, mbases, namespace): if name: return metaclass.__new__(metaclass, name, Bases, namespace) return super(NewMeta, mcls).__new__(mcls, "", mbases, {}) return NewMeta("", tuple(), {}) ● Passo 1 – Criar classe com metaclasse fakePasso 1 – Criar classe com metaclasse fake – Apenas para obter o “namespace”Apenas para obter o “namespace” ● Passo 2 – Usar a metaclasse fornecidaPasso 2 – Usar a metaclasse fornecida
  27. 27. 27 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães PrintPrint ● Python 2Python 2 – Statement / comandoStatement / comando – print >>f, “string”print >>f, “string” – print “a”, “b”print “a”, “b” – print “string”,print “string”, ● Python 3Python 3 – FunçãoFunção – print(“string”, file = f)print(“string”, file = f) – print(“a”, “b”, sep=“ ”)print(“a”, “b”, sep=“ ”) – print(“string”, end=“ ”)print(“string”, end=“ ”) ● Solução (parcial) imediataSolução (parcial) imediata – from __future__ import print_functionfrom __future__ import print_function Almost there...Almost there...
  28. 28. 28 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Unicode!!!Unicode!!! ● Nomes de variável em unicodeNomes de variável em unicode ● *.py em UTF-8 (Python 3)*.py em UTF-8 (Python 3) – No Python 2, em uma das 2 primeiras linhas:No Python 2, em uma das 2 primeiras linhas: # coding: utf-8# coding: utf-8 ● Pensar no unicode (str do Python 3) como um objeto.Pensar no unicode (str do Python 3) como um objeto. – Encode: codifica o unicode para uma string de bytesEncode: codifica o unicode para uma string de bytes – Decode: dos bytes, obtém o unicodeDecode: dos bytes, obtém o unicode ● The Absolute Minimum Every Software DeveloperThe Absolute Minimum Every Software Developer Absolutely, Positively Must Know About UnicodeAbsolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)and Character Sets (No Excuses!) http://www.joelonsoftware.com/articles/Unicode.htmlhttp://www.joelonsoftware.com/articles/Unicode.html
  29. 29. 29 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Unicode!!!Unicode!!! ● u“texto” (Python 3.3 e 2.x)u“texto” (Python 3.3 e 2.x) ● from __future__ import unicode_literalsfrom __future__ import unicode_literals – Funciona no Python 3.2Funciona no Python 3.2 ● Conversão manual (testar tipo)Conversão manual (testar tipo) ● Provavelmente o aspecto mais difícil durante aProvavelmente o aspecto mais difícil durante a compatibilizaçãocompatibilização – os.urandom no simplekv (flask-kvsession)os.urandom no simplekv (flask-kvsession)
  30. 30. 30 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Itertools e functoolsItertools e functools ● reducereduce – from functools import reducefrom functools import reduce ● zip, map, filter (e zip_longest)zip, map, filter (e zip_longest) – Python 2: ListasPython 2: Listas – Python 3: Comportamento tardio (lazy), similar aoPython 3: Comportamento tardio (lazy), similar ao izip, imap, ifilter do itertools do Python 2izip, imap, ifilter do itertools do Python 2 ● ItertoolsItertools – Não possui mais izip, imap, ifilter, izip_longestNão possui mais izip, imap, ifilter, izip_longest – Novo accumulateNovo accumulate
  31. 31. 31 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães DivisãoDivisão ● 1 / 21 / 2 – 0 no Python 2 (int)0 no Python 2 (int) – 0.5 no Python 3 (float)0.5 no Python 3 (float) ● 1 // 21 // 2 – 0 no Python 2 (int)0 no Python 2 (int) – 0 no Python 3 (int)0 no Python 3 (int) ● Solução imediataSolução imediata – from __future__ import divisionfrom __future__ import division
  32. 32. 32 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Parte 4Parte 4 Diferenças inusitadasDiferenças inusitadas
  33. 33. 33 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Arredondamento de pontoArredondamento de ponto flutuanteflutuante In [1]: round(.5) Out[1]: 1.0 In [2]: round(-.5) Out[2]: -1.0 In [1]: round(.5) Out[1]: 1.0 In [2]: round(-.5) Out[2]: -1.0 ● Python 2Python 2 ● Python 3Python 3 ● Solução? Depende do comportamento desejadoSolução? Depende do comportamento desejado – audiolazy.rintaudiolazy.rint In [1]: round(.5) Out[1]: 0 In [2]: round(-.5) Out[2]: 0 In [1]: round(.5) Out[1]: 0 In [2]: round(-.5) Out[2]: 0
  34. 34. 34 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Namespace da classeNamespace da classe ● Python 2Python 2 – Funciona okFunciona ok ● Python 3Python 3 – NameError: globalNameError: global name 'data' is notname 'data' is not defineddefined class A(object): data = [1, 2, 3] data_powers = [[x ** n for x in data] for n in range(3)] class A(object): data = [1, 2, 3] data_powers = [[x ** n for x in data] for n in range(3)] ● CompatibilizarCompatibilizar – data_powers = (lambda data: […])(data)data_powers = (lambda data: […])(data) – Deixar fora da classeDeixar fora da classe – Colocar no __init__ ou no __new__ da metaclasseColocar no __init__ ou no __new__ da metaclasse
  35. 35. 35 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Parte 4Parte 4 FinalizaçãoFinalização
  36. 36. 36 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Python 2.6 e 2.7Python 2.6 e 2.7 ● Apenas no Python 2.7Apenas no Python 2.7 – Dict comprehensionDict comprehension ● dict((k, v) for k, v in my_iterable)dict((k, v) for k, v in my_iterable) – Set comprehensionSet comprehension ● set(el for el in my_iterable)set(el for el in my_iterable) – collections.OrderedDictcollections.OrderedDict ● pip install ordereddictpip install ordereddict ● Outros features do Python 3.1 (backported)Outros features do Python 3.1 (backported) http://docs.python.org/dev/whatsnew/2.7.htmlhttp://docs.python.org/dev/whatsnew/2.7.html Comprehension com {}: Comprehension com {}: apenas Python 2.7, 3.1 e apenas Python 2.7, 3.1 e mais recentes mais recentes
  37. 37. 37 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães sixsix ● Pacote de compatibilizaçãoPacote de compatibilização – Funções para iterar em dicionáriosFunções para iterar em dicionários – Constantes com tipos para uso com isinstanceConstantes com tipos para uso com isinstance – callable (Ausente no Python 3 até o 3.1)callable (Ausente no Python 3 até o 3.1) – Preocupação com Python 2.4 e 2.5Preocupação com Python 2.4 e 2.5 ● Avaliação tardiaAvaliação tardia – Não importa nada à toaNão importa nada à toa – Engana análise para auto-completeEngana análise para auto-complete ● Metaclasse (mantém um nível hierárquico adicional)Metaclasse (mantém um nível hierárquico adicional) – class A(with_metaclass(Meta, Base)) # Apenas uma baseclass A(with_metaclass(Meta, Base)) # Apenas uma base – Neste caso, a audiolazy.meta é mais geralNeste caso, a audiolazy.meta é mais geral Utilizado pelo Utilizado peloMatPlotLib MatPlotLib
  38. 38. 38 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães ninenine ● Favorece o Python 3Favorece o Python 3 ● Para código a partir do Python 2.6Para código a partir do Python 2.6 ● Boilerplate sugeridoBoilerplate sugerido # -*- coding: utf-8 -*- from __future__ import (absolute_import, division, print_function, unicode_literals) from nine import (IS_PYTHON2, str, basestring, native_str, chr, integer_types, class_types, range, range_list, reraise, iterkeys, itervalues, iteritems, map, zip, filter, input, implements_iterator, implements_to_string, implements_repr, nine, nimport) # -*- coding: utf-8 -*- from __future__ import (absolute_import, division, print_function, unicode_literals) from nine import (IS_PYTHON2, str, basestring, native_str, chr, integer_types, class_types, range, range_list, reraise, iterkeys, itervalues, iteritems, map, zip, filter, input, implements_iterator, implements_to_string, implements_repr, nine, nimport)
  39. 39. 39 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Alternativas à compatibilizaçãoAlternativas à compatibilização ● Conversão automáticaConversão automática – Distribute com 2to3 ou 3to2Distribute com 2to3 ou 3to2 ● Conversão manualConversão manual – Branches para cada versãoBranches para cada versão ● IncompatibilidadeIncompatibilidade – Código [parcialmente] restrito a versões específicasCódigo [parcialmente] restrito a versões específicas ● ““Imports” localizados apenas onde necessárioImports” localizados apenas onde necessário
  40. 40. 40 Compatibilidade entre Python 2 e 3Compatibilidade entre Python 2 e 3 2013-10-02 – Danilo J. S. Bellini – @danilobellini2013-10-02 – Danilo J. S. Bellini – @danilobellini Brasília – DFBrasília – DF Centro de ConvençõesCentro de Convenções Ulysses GuimarãesUlysses Guimarães Obrigado!Obrigado! >>> from audiolazy import lazy_compat as compat >>> dir(compat) ['INT_TYPES', 'NEXT_NAME', 'PYTHON2', 'SOME_GEN_TYPES', 'STR_TYPES', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', 'builtins', 'im_func', 'it', 'iteritems', 'itervalues', 'meta', 'orange', 'sys', 'types', 'xfilter', 'xmap', 'xrange', 'xzip', 'xzip_longest'] >>> from audiolazy import lazy_compat as compat >>> dir(compat) ['INT_TYPES', 'NEXT_NAME', 'PYTHON2', 'SOME_GEN_TYPES', 'STR_TYPES', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', 'builtins', 'im_func', 'it', 'iteritems', 'itervalues', 'meta', 'orange', 'sys', 'types', 'xfilter', 'xmap', 'xrange', 'xzip', 'xzip_longest'] Perguntas?Perguntas? https://github.com/danilobellini/audiolazyhttps://github.com/danilobellini/audiolazy @danilobellini@danilobellini danilo [dot] bellini [at] gmail [dot] comdanilo [dot] bellini [at] gmail [dot] com

×