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
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Python: the coolest is yet to come
1. The COOLEST is yet
TO COME
{
“event”: “PDI DEVCON 2013”
“author”: “Pablo Enfedaque”
“twi5er”: “pablitoev56”
2. >
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”}
3. The super function
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
4. 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
Let’s implement a SilentDict
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
5. 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
Let’s implement a SilentDict
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
6. >
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”}
7. The yield from statement
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
9. 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]
Let’s implement itertools.chain
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
10. >
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”}
11. The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
12. from urllib.request import urlopen
from urllib.error import URLError
class 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
def 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")
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
13. $ python3.4 raise_from_none_examples.py
Traceback (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
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
14. $ python3.4 raise_from_none_examples.py
Traceback (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
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
15. from urllib.request import urlopen
from urllib.error import URLError
class 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 exc
def 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")
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
16. $ python3.4 raise_from_none_examples.py
Traceback (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
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
17. from urllib.request import urlopen
from urllib.error import URLError
class 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 None
def 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")
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
18. $ python3.4 raise_from_none_examples.py
Traceback (most recent call last):
File "raise_from_none_examples.py", line
main_app("http://unknown_host:8765")
File "raise_from_none_examples.py", line
print(call_the_requester(url))
File "raise_from_none_examples.py", line
call_the_requester
return requester(url)
File "raise_from_none_examples.py", line
raise CustomException from None
__main__.CustomException
40, in <module>
36, in main_app
32, in
28, in requester
The new exception chaining
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
19. >
Several PEPs involved:
>
PEP 3134: Exception Chaining and Embedded
Tracebacks
>
>
PEP 409: Suppressing exception context
>
>
h5p://www.python.org/dev/peps/pep-‐‑3134
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”}
27. $ 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.cfg
home = /Library/Frameworks/Python.framework/Versions/3.4/bin
include-system-site-packages = false
version = 3.4.0
$ pyvenv /tmp/test_venv --symlinks --clear --system-site-packages
$ cat /tmp/test_venv/pyvenv.cfg
home = /Library/Frameworks/Python.framework/Versions/3.4/bin
include-system-site-packages = true
version = 3.4.0
$ ls -lAhtr /tmp/test_venv/bin/python3.4
lrwxr-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
Python virtual environments
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
28. $ 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) ...$ python
Python 3.4.0a4 (v3.4.0a4:e245b0d7209b, Oct 20 2013, 02:43:50)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "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
Python virtual environments
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
29. >
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”}
30. >
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”}
32. RED, ORANGE, GREEN = range(3) # Colors
STOPPED, RUNNING = range(2)
# Statuses
class 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
Let’s implement a traffic light
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
33. RED, ORANGE, GREEN = range(3) # Colors
STOPPED, RUNNING = range(2)
# Statuses
class 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
Let’s implement a traffic light
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
34. RED, ORANGE, GREEN = range(3) # Colors
STOPPED, RUNNING = range(2)
# Statuses
class 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
Let’s implement a traffic light
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
35. RED, ORANGE, GREEN = range(3) # Colors
STOPPED, RUNNING = range(2)
# Statuses
class 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 ORANGE
True
>>> (RUNNING + ORANGE) * GREEN
4
Let’s implement a traffic light
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
36. from enum import Enum
Color = Enum("Color", "red orange green")
# Colors
Status = Enum("Status", "stopped running") # Statuses
class 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)
Introducing the enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
37. >>> 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.red
False
>>> Status.running is Color.orange
False
>>> (Status.running + Color.orange) * Color.green
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'Status' and 'Color'
Introducing the enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
38. 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 name
orange
>>> print(Color["orange"])
# we can get the enum member from its name
Color.orange
>>> print(Color.orange.value) # we can retrieve a member value
10
>>> print(Color(10))
# we can get the enum member from its value
Color.orange
More about enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
39. class Color(Enum):
red = 0
orange = 10
green = 20
class Status(Enum):
running = 0
stopped = 1
class 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
More about enum module
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
40. >
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”}
41. >
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”}
43. >
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”}
44. >
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”}
45. >
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”}
47. Are we done yet?
Q&A
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
48. Are we done yet?
>
Not yet
>
Only 22 slides missing
>
16 only with pictures, and even 1 animated GIF
>
Sorry, no ki5ens
Q&A
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
49. Should we move now to
Python 3?
Q&A
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
50. Should we move now to
Python 3?
>
YES
>
Well, maybe NO
>
Well, let me explain
Q&A
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
52. 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”}
53. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
54. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
55. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
56. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
57. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
58. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
59. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
60. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
61. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
62. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
63. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
64. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
65. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
66. The long journey to Python 3
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
67. Meanwhile, most of the community
{ “event”: “PDI DEVCON 2013”, “author”: “Pablo Enfedaque”, “twi5er”: “pablitoev56”}
68. >
Great features are waiting us in Python 3
>
We are beyond half the planned life of Python 2.7
>
>
Most 3rd party dependencies already in Python 3
>
>
Python 2.6 is officially retired with 2.6.9 release
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”}