Upload
pablo-enfedaque
View
406
Download
1
Embed Size (px)
DESCRIPTION
In this talk we will make a tour through the most important changes and new features in the language and its standard library, such as enums, single-dispatch generic functions, Tulip, yield from, raise from None, contextlib... And yes, we will talk about Python 3. GitHub repository with the code of the examples: https://github.com/pablito56/coolest_is_yet_to_come
Citation preview
{The COOLEST is yet
TO COME “event”: “PDI DEVCON 2013” “author”: “Pablo Enfedaque” “twi5er”: “pablitoev56”
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> Today we are going to see a quick tour through Python’s newest features > The new super function > The yield from statement
> The new exception chaining > Single-‐‑dispatch generic functions > Python virtual environments > The enum module > The asyncio module
> And lots of other new features
Welcome!
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The super function
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement a SilentDict
class SilentDict(dict): def __getitem__(self, key): """Called to implement evaluation of self[key] :returns: None by default """ try: return super(SilentDict, self).__getitem__(key) except KeyError: return None>>> d = SilentDict()>>> print (d[“a”])None>>> d = SilentDict({"a": 1, "b": 2})>>> print(d["a"])1>>> print(d["a"])None
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement a SilentDict
class SilentDict(dict): def __getitem__(self, key): """Called to implement evaluation of self[key] :returns: None by default """ try: return super().__getitem__(key) except KeyError: return None>>> d = SilentDict()>>> print (d[“a”])None>>> d = SilentDict({"a": 1, "b": 2})>>> print(d["a"])1>>> print(d["a"])None
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> h5p://docs.python.org/3/library/functions.html#super > PEP 3135: New Super
> h5p://www.python.org/dev/peps/pep-‐‑3135/
> Introduced in Python 3.0
> Standard Library updated to use it > No official backport
The super function
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The yield from statement
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement itertools.chain
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement itertools.chain
def chain(*iterables): # chain('ABC', 'DEF') --> A B C D E F for it in iterables: yield from it>>> list(chain('ABC', 'DEF'))['A', 'B', 'C', 'D', 'E', 'F']>>> list(chain([1, 2, 3], (4, 5, 6), [7, 8, 9]))[1, 2, 3, 4, 5, 6, 7, 8, 9]
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> PEP 380: Syntax for Delegating to a Subgenerator > h5p://www.python.org/dev/peps/pep-‐‑0380/
> Introduced in Python 3.3 > No backport
The yield from statement
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
from urllib.request import urlopenfrom urllib.error import URLErrorclass CustomException(Exception): """Out custom exception for this example""”def requester(url): """Open and read given url""" try: return urlopen(url).readall() except URLError: raise CustomExceptiondef call_the_requester(url): return requester(url)def main_app(url): print(call_the_requester(url))if __name__ == "__main__": main_app("http://unknown_host:8765")
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
$ python3.4 raise_from_none_examples.pyTraceback (most recent call last):... File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 1255, in do_open raise URLError(err)urllib.error.URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>During handling of the above exception, another exception occurred:Traceback (most recent call last): File "raise_from_none_examples.py", line 39, in <module> main_app("http://unknown_host:8765") File "raise_from_none_examples.py", line 35, in main_app print(call_the_requester(url)) File "raise_from_none_examples.py", line 31, in call_the_requester return requester(url) File "raise_from_none_examples.py", line 27, in requester raise CustomException__main__.CustomException
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
$ python3.4 raise_from_none_examples.pyTraceback (most recent call last):... File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/urllib/request.py", line 1255, in do_open raise URLError(err)urllib.error.URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>During handling of the above exception, another exception occurred:Traceback (most recent call last): File "raise_from_none_examples.py", line 39, in <module> main_app("http://unknown_host:8765") File "raise_from_none_examples.py", line 35, in main_app print(call_the_requester(url)) File "raise_from_none_examples.py", line 31, in call_the_requester return requester(url) File "raise_from_none_examples.py", line 27, in requester raise CustomException__main__.CustomException
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
from urllib.request import urlopenfrom urllib.error import URLErrorclass CustomException(Exception): """Out custom exception for this example""”def requester(url): """Open and read given url""" try: return urlopen(url).readall() except URLError as exc: raise CustomException from excdef call_the_requester(url): return requester(url)def main_app(url): print(call_the_requester(url))if __name__ == "__main__": main_app("http://unknown_host:8765")
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
$ python3.4 raise_from_none_examples.pyTraceback (most recent call last):... File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/urllib/request.py", line 1242, in do_open raise URLError(err)urllib.error.URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>The above exception was the direct cause of the following exception:Traceback (most recent call last): File "raise_from_none_examples.py", line 40, in <module> main_app("http://unknown_host:8765") File "raise_from_none_examples.py", line 36, in main_app print(call_the_requester(url)) File "raise_from_none_examples.py", line 32, in call_the_requester return requester(url) File "raise_from_none_examples.py", line 28, in requester raise CustomException from exc__main__.CustomException
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
from urllib.request import urlopenfrom urllib.error import URLErrorclass CustomException(Exception): """Out custom exception for this example""”def requester(url): """Open and read given url""" try: return urlopen(url).readall() except URLError: raise CustomException from Nonedef call_the_requester(url): return requester(url)def main_app(url): print(call_the_requester(url))if __name__ == "__main__": main_app("http://unknown_host:8765")
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The new exception chaining
$ python3.4 raise_from_none_examples.pyTraceback (most recent call last): File "raise_from_none_examples.py", line 40, in <module> main_app("http://unknown_host:8765") File "raise_from_none_examples.py", line 36, in main_app print(call_the_requester(url)) File "raise_from_none_examples.py", line 32, in call_the_requester return requester(url) File "raise_from_none_examples.py", line 28, in requester raise CustomException from None__main__.CustomException
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> Several PEPs involved: > PEP 3134: Exception Chaining and Embedded
Tracebacks > h5p://www.python.org/dev/peps/pep-‐‑3134
> PEP 409: Suppressing exception context > h5p://www.python.org/dev/peps/pep-‐‑0409/
> PEP 415: Implement context suppression with exception a5ributes > h5p://www.python.org/dev/peps/pep-‐‑0415
> Introduced in Python 3.0 and 3.3 > No official backport
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Single-‐‑dispatch generic functions
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s create some animals
class Duck: def quack(self): print("quack")class Cat: def meow(self): print("meow")class Dog: def bark(self): print("bark”)class Cow: def moo(self): print("moo")donald = Duck()garfield = Cat()milu = Dog()milka = Cow()
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s play animals’ sounds
def make_sound(animal): if isinstance(animal, Duck): animal.quack() elif isinstance(animal, Cat): animal.meow() elif isinstance(animal, Dog): animal.bark() else: raise NotImplementedError("Unknown animal")>>> make_sound(donald)quack>>> make_sound(garfield)meow>>> make_sound(milu)bark>>> make_sound(milka)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 11, in make_soundNotImplementedError: Unknown animal
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Single-‐‑dispatch generic functions
import [email protected] make_sound(animal): raise NotImplementedError("Unknown animal")@make_sound.register(Duck)def make_duck_sound(animal): animal.quack()@make_sound.register(Cat)def make_cat_sound(animal): animal.meow()@make_sound.register(Dog)def _(animal): animal.bark()
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Single-‐‑dispatch generic functions
>>> make_sound(donald)quack>>> make_sound(garfield)meow>>> make_sound(milu)bark>>> make_sound(milka)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/functools.py", line 632, in wrapper return dispatch(args[0].__class__)(*args, **kw) File "<stdin>", line 5, in make_soundNotImplementedError: Unknown animal
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> h5p://docs.python.org/dev/library/functools.html#functools.singledispatch > PEP 443: Single-‐‑dispatch generic functions
> h5p://www.python.org/dev/peps/pep-‐‑0443/
> Introduced in Python 3.4
> No official backport
Single-‐‑dispatch generic functions
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Python virtual environments
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Python virtual environments
$ pyvenv /tmp/test_venv$ ls /tmp/test_venv/bin include lib pyvenv.cfg$ ls /tmp/test_venv/bin/activate activate.csh activate.fish python python3 python3.4$ cat /tmp/test_venv/pyvenv.cfghome = /Library/Frameworks/Python.framework/Versions/3.4/bininclude-system-site-packages = falseversion = 3.4.0$ pyvenv /tmp/test_venv --symlinks --clear --system-site-packages$ cat /tmp/test_venv/pyvenv.cfghome = /Library/Frameworks/Python.framework/Versions/3.4/bininclude-system-site-packages = trueversion = 3.4.0$ ls -lAhtr /tmp/test_venv/bin/python3.4lrwxr-xr-x 1 pev wheel 63B 5 nov 00:21 /tmp/test_venv/bin/python3.4 -> /Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Python virtual environments
$ source /tmp/test_venv/bin/activate(test_venv) ...$ which python/tmp/test_venv/bin/python(test_venv) ...$ which python3.4/tmp/test_venv/bin/python3.4(test_venv) ...$ pythonPython 3.4.0a4 (v3.4.0a4:e245b0d7209b, Oct 20 2013, 02:43:50)[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import sys>>> sys.prefix, sys.base_prefix('/private/tmp/test_venv', '/Library/Frameworks/Python.framework/Versions/3.4')>>> sys.exec_prefix, sys.base_exec_prefix('/private/tmp/test_venv', '/Library/Frameworks/Python.framework/Versions/3.4')(test_venv) ...$ deactivate$ which python/usr/bin/python
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> Features > Supports symbolic links (recommended)
> Access both environment and system site-‐‑packages
> pyvenv.cfg environment configuration file: > home: path to original Python installation bin > include-‐‑system-‐‑site-‐‑packages: access system site-‐‑packages
after the environment site-‐‑packages > version: Python version in use
> Public API to let 3rd party virtual environments customise the environment creation > Subclass EnvBuilder and redefine desired methods
Python virtual environments
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> h5p://docs.python.org/3/library/venv.html > PEP 405: Python Virtual Environments
> h5p://www.python.org/dev/peps/pep-‐‑0405/
> Introduced in Python 3.3 > No official backport, although quite similar to
virtualenv
Python virtual environments
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement a traffic light
RED, ORANGE, GREEN = range(3) # ColorsSTOPPED, RUNNING = range(2) # Statusesclass TrafficLight: def __init__(self, light_color, status): assert light_color in (RED, ORANGE, GREEN), "Not a valid color" assert status in (RUNNING, STOPPED), "Not a valid status" self.color = light_color self.status = status def print_state(self): color_name = "red" if self.color == RED else "green" if self.color == GREEN else "orange" status_name = "running" if self.status == RUNNING else "stopped" print("Traffic light is {} in color {}".format(status_name, color_name))>>> my_semaphore = TrafficLight(RUNNING, RED)>>> my_semaphore.print_state()Traffic light is stopped in color orange
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement a traffic light
RED, ORANGE, GREEN = range(3) # ColorsSTOPPED, RUNNING = range(2) # Statusesclass TrafficLight: def __init__(self, light_color, status): assert light_color in (RED, ORANGE, GREEN), "Not a valid color" assert status in (RUNNING, STOPPED), "Not a valid status" self.color = light_color self.status = status def print_state(self): color_name = "red" if self.color == RED else "green" if self.color == GREEN else "orange" status_name = "running" if self.status == RUNNING else "stopped" print("Traffic light is {} in color {}".format(status_name, color_name))>>> my_semaphore = TrafficLight(RUNNING, RED)>>> my_semaphore.print_state()Traffic light is stopped in color orange
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement a traffic light
RED, ORANGE, GREEN = range(3) # ColorsSTOPPED, RUNNING = range(2) # Statusesclass TrafficLight: def __init__(self, light_color, status): assert light_color in (RED, ORANGE, GREEN), "Not a valid color" assert status in (RUNNING, STOPPED), "Not a valid status" self.color = light_color self.status = status def print_state(self): color_name = "red" if self.color == RED else "green" if self.color == GREEN else "orange" status_name = "running" if self.status == RUNNING else "stopped" print("Traffic light is {} in color {}".format(status_name, color_name))>>> my_semaphore = TrafficLight(RUNNING, RED)>>> my_semaphore.print_state()Traffic light is stopped in color orange
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Let’s implement a traffic light
RED, ORANGE, GREEN = range(3) # ColorsSTOPPED, RUNNING = range(2) # Statusesclass TrafficLight: def __init__(self, light_color, status): assert light_color in (RED, ORANGE, GREEN), "Not a valid color" assert status in (RUNNING, STOPPED), "Not a valid status" self.color = light_color self.status = status def print_state(self): color_name = "red" if self.color == RED else "green" if self.color == GREEN else "orange" status_name = "running" if self.status == RUNNING else "stopped" print("Traffic light is {} in color {}".format(status_name, color_name))>>> STOPPED is RED and RUNNING is ORANGETrue>>> (RUNNING + ORANGE) * GREEN4
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Introducing the enum module
from enum import EnumColor = Enum("Color", "red orange green") # ColorsStatus = Enum("Status", "stopped running") # Statusesclass TrafficLight: def __init__(self, light_color, status): assert light_color in Color, "Not a valid color" assert status in Status, "Not a valid status" self.color = light_color self.status = status def print_state(self): color_name = "red" if self.color == Color.red else "green" if self.color == Color.green else "orange" status_name = "running" if self.status == Status.running else "stopped" print("Traffic light is {} in color {}".format(status_name, color_name))my_semaphore = TrafficLight(Status.running, Color.red)
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Introducing the enum module
>>> my_semaphore = TrafficLight(Status.running, Color.red)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in __init__AssertionError: Not a valid color>>> my_semaphore = TrafficLight(Color.red, Status.running)>>> my_semaphore.print_state()Traffic light is running in color red>>> Status.stopped is Color.redFalse>>> Status.running is Color.orangeFalse>>> (Status.running + Color.orange) * Color.greenTraceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for +: 'Status' and 'Color'
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
More about enum module
class Color(Enum): # enumaration red = 0 orange = 10 # enumeration members green = 20 # custom non-consecutive values ruby = 0 # aliases>>> print(Color.green)Color.green>>> print(repr(Color.green))<Color.green: 20>>>> print(repr(Color.ruby)) # this is an alias<Color.red: 0>>>> print(Color.orange.name) # we can retrieve a member nameorange>>> print(Color["orange"]) # we can get the enum member from its nameColor.orange>>> print(Color.orange.value) # we can retrieve a member value10>>> print(Color(10)) # we can get the enum member from its valueColor.orange
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
More about enum module
class Color(Enum): red = 0 orange = 10 green = 20class Status(Enum): running = 0 stopped = 1class TrafficLight: def __init__(self, light_color, status): assert light_color in Color, "Not a valid color" assert status in Status, "Not a valid status" self.color = light_color self.status = status def print_state(self): print("Traffic light is {} in color {}".format(self.status.name, self.color.name))>>> my_semaphore = TrafficLight(Color.red, Status.running)>>> my_semaphore.print_state()Traffic light is running in color red
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> And still more features > Iteration over enumeration members
> Ordered dictionary __members__ special a5ribute > Define methods and class methods
> Even redefine __str__ or __repr__ > IntEnum to preserve old int behaviour > @enum.unique to enforce no aliases are defined > Possibility to define other custom Enum sublcasses > Functional API
More about enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> h5p://docs.python.org/3.4/library/enum.html > PEP 435: Adding an Enum type to the Python
standard library > h5p://www.python.org/dev/peps/pep-‐‑0435/
> Introduced in Python 3.4 > Standard Library updated to use enums
> IntEnum when backwards-‐‑compatibility broken > Enum in new developments and internal modules
> Official backport available in PyPi > h5ps://pypi.python.org/pypi/enum34/
The enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The asyncio module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> Python’s asynchronous IO Support Rebooted > No new language features, no new lib extensions > Based on a customisable event loop
> Interface to manage the event loop and its policies > Interface to implement or adapt event loops
> Different 3rd party async frameworks could interoperate
> Coroutines, futures and tasks > Transports and protocols > Use yield from to delegate or callbacks
The asyncio module (aka. Tulip)
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> h5p://docs.python.org/3.4/library/enum.html > PEP 3156: Asynchronous IO Support Rebooted:
the "ʺasyncio"ʺ Module > h5p://www.python.org/dev/peps/pep-‐‑3156/
> Reference implementation in Python 3.4
> Expected final status in Python 3.5
> Backport to 3.3 available in PyPi > h5ps://pypi.python.org/pypi/asyncio/0.1.1
The asyncio module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> unicode, unicode everywhere > generators, generators everywhere
> or iterators
> uniNest.mock (port of Michael Foord’s mock) > contextlib.ExitStack and contextlib.ContextDecorator
> Be5er GIL (but still Global Interpreter Lock) > concurrent.futures for async computation > Qualified name for classes and functions > selectors module
> …
And still lots of new features
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Q&A
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Q&A
Are we done yet?
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> Not yet > Only 22 slides missing
> 16 only with pictures, and even 1 animated GIF > Sorry, no ki5ens
Q&A
Are we done yet?
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Q&A
Should we move now to Python 3?
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> YES > Well, maybe NO
> Well, let me explain
Q&A
Should we move now to Python 3?
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
h5p://www.python.org/download/releases/2.7/ Release schedule: > … > 2.7.0 final: July 3, 2010 > … > 2.7.6 candidate 1: October 26, 2013 > ??? > 2.7.X end of support: ≈ 2016
Python 2.7
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
h5p://www.python.org/download/releases/3.4.0/ Release schedule: > 3.4.0 alpha 4: October 20, 2013 > 3.4.0 beta 1 (feature freeze): November 24, 2013 > 3.4.0 beta 2: January 5, 2014 > 3.4.0 candidate 1: January 19, 2014 > 3.4.0 candidate 2: February 2, 2014 > 3.4.0 final: February 23, 2014
Python 3.4
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Meanwhile, most of the community
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
> Great features are waiting us in Python 3 > We are beyond half the planned life of Python 2.7
> Python 2.6 is officially retired with 2.6.9 release
> Most 3rd party dependencies already in Python 3 > Or we could return to OSS all that we have been given
> Porting to Python 3 is not such a big deal > In most of the cases
> So, no more excuses
> It’s time to start moving to Python 3
Conclusions
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Conclusions
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
Q&A
Thanks for coming!
Slides: h5p://goo.gl/Yrzt0Q Code: h5p://goo.gl/V9bv72