SlideShare uma empresa Scribd logo
1 de 40
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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

Mais conteúdo relacionado

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

Algoritmos e programacao_em_python
Algoritmos e programacao_em_pythonAlgoritmos e programacao_em_python
Algoritmos e programacao_em_pythonArtur Santos
 
(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em PythonDanilo J. S. Bellini
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)Danilo J. S. Bellini
 
Desenvolva para o Mundo - Internacionalização de Sistemas com Zend Framework
Desenvolva para o Mundo - Internacionalização de Sistemas com Zend FrameworkDesenvolva para o Mundo - Internacionalização de Sistemas com Zend Framework
Desenvolva para o Mundo - Internacionalização de Sistemas com Zend FrameworkEduardo Bona
 
Programar 1215
Programar  1215Programar  1215
Programar 1215tugafree
 
Revista programar 51
Revista programar 51Revista programar 51
Revista programar 51Renato Lucena
 
Introdução a linguagem Python
Introdução a linguagem PythonIntrodução a linguagem Python
Introdução a linguagem PythonLuciano Ramalho
 
Iniciando em Python
Iniciando em PythonIniciando em Python
Iniciando em PythonRober Guerra
 
Provas de Informática Comentadas para o Concurso do INSS
Provas de Informática Comentadas para o Concurso do INSSProvas de Informática Comentadas para o Concurso do INSS
Provas de Informática Comentadas para o Concurso do INSSEstratégia Concursos
 
Framework de GameAnalytics para Jogos Moveis 2D Tipo Plataforma
Framework de GameAnalytics para Jogos Moveis 2D Tipo PlataformaFramework de GameAnalytics para Jogos Moveis 2D Tipo Plataforma
Framework de GameAnalytics para Jogos Moveis 2D Tipo PlataformaBeatriz Vaz Pinto
 
Gerenciamento e automatização de configuração de uma infraestrutura com Puppet
Gerenciamento e automatização de configuração de uma infraestrutura com PuppetGerenciamento e automatização de configuração de uma infraestrutura com Puppet
Gerenciamento e automatização de configuração de uma infraestrutura com PuppetAécio Pires
 
Arduino + Python: produtividade ao extremo
Arduino + Python: produtividade ao extremoArduino + Python: produtividade ao extremo
Arduino + Python: produtividade ao extremoÁlvaro Justen
 
Oficina Python: Hackeando a Web com Python 3
Oficina Python: Hackeando a Web com Python 3Oficina Python: Hackeando a Web com Python 3
Oficina Python: Hackeando a Web com Python 3Marcel Caraciolo
 
Introdução a linguagem Python: simples e produtiva
Introdução a linguagem Python: simples e produtivaIntrodução a linguagem Python: simples e produtiva
Introdução a linguagem Python: simples e produtivaÁlvaro Justen
 

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

Algoritmos e programacao_em_python
Algoritmos e programacao_em_pythonAlgoritmos e programacao_em_python
Algoritmos e programacao_em_python
 
Mergulhando no ecossistema .NET
Mergulhando no ecossistema .NETMergulhando no ecossistema .NET
Mergulhando no ecossistema .NET
 
(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
 
Desenvolva para o Mundo - Internacionalização de Sistemas com Zend Framework
Desenvolva para o Mundo - Internacionalização de Sistemas com Zend FrameworkDesenvolva para o Mundo - Internacionalização de Sistemas com Zend Framework
Desenvolva para o Mundo - Internacionalização de Sistemas com Zend Framework
 
Programar 1215
Programar  1215Programar  1215
Programar 1215
 
Revista programar 51
Revista programar 51Revista programar 51
Revista programar 51
 
Introdução a linguagem Python
Introdução a linguagem PythonIntrodução a linguagem Python
Introdução a linguagem Python
 
Python-Fenalivre-Imed
Python-Fenalivre-ImedPython-Fenalivre-Imed
Python-Fenalivre-Imed
 
Iniciando em Python
Iniciando em PythonIniciando em Python
Iniciando em Python
 
Provas de Informática Comentadas para o Concurso do INSS
Provas de Informática Comentadas para o Concurso do INSSProvas de Informática Comentadas para o Concurso do INSS
Provas de Informática Comentadas para o Concurso do INSS
 
Introdução ao git
Introdução ao gitIntrodução ao git
Introdução ao git
 
Computação Científica com Python 2013
Computação Científica com Python 2013Computação Científica com Python 2013
Computação Científica com Python 2013
 
Framework de GameAnalytics para Jogos Moveis 2D Tipo Plataforma
Framework de GameAnalytics para Jogos Moveis 2D Tipo PlataformaFramework de GameAnalytics para Jogos Moveis 2D Tipo Plataforma
Framework de GameAnalytics para Jogos Moveis 2D Tipo Plataforma
 
Gerenciamento e automatização de configuração de uma infraestrutura com Puppet
Gerenciamento e automatização de configuração de uma infraestrutura com PuppetGerenciamento e automatização de configuração de uma infraestrutura com Puppet
Gerenciamento e automatização de configuração de uma infraestrutura com Puppet
 
Arduino + Python: produtividade ao extremo
Arduino + Python: produtividade ao extremoArduino + Python: produtividade ao extremo
Arduino + Python: produtividade ao extremo
 
Pentest conisli07
Pentest conisli07Pentest conisli07
Pentest conisli07
 
Hackeando o Facebook com Python
Hackeando o Facebook com PythonHackeando o Facebook com Python
Hackeando o Facebook com Python
 
Oficina Python: Hackeando a Web com Python 3
Oficina Python: Hackeando a Web com Python 3Oficina Python: Hackeando a Web com Python 3
Oficina Python: Hackeando a Web com Python 3
 
Introdução a linguagem Python: simples e produtiva
Introdução a linguagem Python: simples e produtivaIntrodução a linguagem Python: simples e produtiva
Introdução a linguagem Python: simples e produtiva
 

Mais de Danilo J. S. Bellini

(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask AssíncronoDanilo J. S. Bellini
 
(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!Danilo J. S. Bellini
 
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)Danilo J. S. Bellini
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!Danilo J. S. Bellini
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)Danilo J. S. Bellini
 
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0Danilo J. S. Bellini
 
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)Danilo J. S. Bellini
 
(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e toxDanilo J. S. Bellini
 
(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazyDanilo J. S. Bellini
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!Danilo J. S. Bellini
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...Danilo J. S. Bellini
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazyDanilo J. S. Bellini
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com PythonDanilo J. S. Bellini
 
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojosDanilo J. S. Bellini
 
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...Danilo J. S. Bellini
 

Mais de Danilo J. S. Bellini (19)

(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
(2018-08-25) [Flask Conf] Introdução ao Sanic - O Flask Assíncrono
 
(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!(2018-07-14) [Just Python] Números no Python!
(2018-07-14) [Just Python] Números no Python!
 
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
 
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
(2016-08-13) [Grupy-SP] Plugin pytest-doctest-custom v1.0.0
 
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
(2015-01-29/30) [WTA2015] Adaptatividade em Python (Tutorial)
 
(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox(2014-11-05) [PythonBrasil] Testando com py.test e tox
(2014-11-05) [PythonBrasil] Testando com py.test e tox
 
(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy(2014-10-27) [SETI-UFLA-MG] AudioLazy
(2014-10-27) [SETI-UFLA-MG] AudioLazy
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
 
(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy
 
(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy
 
(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
 
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
 
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
 
(2013-05-03) AudioLazy - Slides
(2013-05-03) AudioLazy - Slides(2013-05-03) AudioLazy - Slides
(2013-05-03) AudioLazy - Slides
 

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

  • 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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